【发布时间】:2020-08-08 08:22:26
【问题描述】:
我有一个自绘图片框 (picGrid),我希望允许用户使用鼠标滚轮进行缩放。那部分很容易。但我想自动滚动,使鼠标下的逻辑点仍然是缩放后鼠标下的逻辑点。
这是我目前所拥有的。它几乎可以工作,但只是不正确。 XScroll 和 YScroll 是我的滚动位置,将用于设置滚动条(除了偏移图像)。
/// <summary>
/// Sets the current zoom percent.
/// </summary>
/// <param name="percent">The percent that the zoom should be set (100 == 1:1 scaling).</param>
/// <param name="x">X coordinate of the mouse in pixels.</param>
/// <param name="y">Y coordinate of the mouse in pixels.</param>
public void SetZoom(int percent, int x, int y)
{
// If needed, this method translates mouse coordinate to logical coordinates
// but doesn't appear to be needed here.
//TranslateCoordinates(ref x, ref y);
// Calculate new scale (1.0f == 1:1 scaling)
float newDrawScale = (float)percent / 100;
// Enforce zoom limits
if (newDrawScale < 0.1f)
newDrawScale = 0.1f;
else if (newDrawScale > 1500.0f)
newDrawScale = 1500.0f;
// Set new zoom (if it's changed)
if (newDrawScale != DrawScale)
{
DrawScale = newDrawScale;
// *** Here's the part that isn't right ***
// Scroll to keep same logical point under mouse
float delta = (DrawScale - 1f);
XScroll = (x * delta);
YScroll = (y * delta);
// Reflect change in scrollbars
UpdateScrollbars();
// Redraw content
picGrid.Invalidate();
}
}
如何计算新的滚动位置,以便缩放后相同的逻辑点保持在鼠标指针下方?
【问题讨论】:
-
@Spektre:谢谢。我花了很多时间查看那个答案(我看到的是你的)。有些事情让我感到困惑。例如,变量名称不是很具有描述性。此外,您的
scr2obj()和obj2scr()方法在我需要减去它们的地方添加x0、y0,并在需要添加它们的地方减去它们。另外,我不知道 gfx objects 是什么,所以我不明白这两个版本的代码。但是,我终于能够根据您的方法提出一个可行的解决方案。我很感激。我已经发布了我的工作代码,以防其他人受益。 -
是的,有更多方法可以在屏幕和世界之间转换,正如您所看到的,它不仅是正/负
offset,如果您在zoom之前或之后应用offset也是如此,如果zoom是直接缩放或倒数,如1/zoom这些给你2^3=8等式组合。如果您添加变换矩阵,那么在所有这些之上还有更多可能的符号,这对于那些只是复制粘贴代码而不知道发生了什么的新手来说是一团糟。
标签: c# c++ .net algorithm graphics