Silverlight 3 - ScaleTransform 或其他放大画布的方法?

发布于 2024-07-25 09:34:51 字数 1397 浏览 2 评论 0原文

我需要能够使用鼠标滚轮放大和缩小画布。 我已经成功设置了鼠标滚轮处理程序,并且当前正在使用 ScaleTransform 来应用缩放; 然而,缩放并不是以“直观”的方式完成的。

我正在尝试实现与您在 MultiScaleImage、Google Maps/Earth 或 Adob​​e Acrobat Reader 中看到的相同样式的“缩放”,但不是使用图像,而是使用控件。 过渡不需要“平滑”或动画(除非它是一种更简单的方法),但功能需要相同。

任何想法或想法将不胜感激,并提前致谢!

编辑:我已经设法使用动画“平滑”缩放:

<Canvas.Resources>
            <Storyboard x:Name="ZoomStoryboard">
                <DoubleAnimation x:Name="ZoomAnimationX"
                                 Storyboard.TargetName="Workspace"
                                 Storyboard.TargetProperty="Canvas.RenderTransform.ScaleTransform.ScaleX"
                                 Duration="0:0:0.2"/>
                <DoubleAnimation x:Name="ZoomAnimationY"
                                 Storyboard.TargetName="Workspace"
                                 Storyboard.TargetProperty="Canvas.RenderTransform.ScaleTransform.ScaleY"
                                 Duration="0:0:0.2"/>
            </Storyboard>
        </Canvas.Resources>

使用以下代码:

_Zoom += (args.Delta / 7);
if (_Zoom < 0.15)
    _Zoom = 0.15;
ZoomAnimationX.To = _Zoom;
ZoomAnimationY.To = _Zoom;
ZoomStoryboard.Begin();
ZoomScale.Text = _Zoom.ToString("0.00") + "x";
_PreviousMousePosition = _CurrentMousePosition

但是,问题仍然出现,它正在缩小左上角,而不是像 Google 地图这样的网站,缩放是“围绕”鼠标。

I need to be able to zoom in and out of a Canvas using the mousewheel. I have successfully set up the mouse wheel handlers and am currently using a ScaleTransform to apply the zoom; however, the scaling is not done in an "intuitive" way.

I'm trying to accomplish the same style of "zooming" as you can see in MultiScaleImage, Google Maps/Earth, or Adobe Acrobat Reader--but NOT with an image, with a control. The transition doesn't need to be "smooth" or animated (unless it's an easier approach), but the functionality needs to be the same.

Any thoughts or ideas would be highly appreciated and thanks in advance!

Edit: I've managed to "smooth" the zoom using animation:

<Canvas.Resources>
            <Storyboard x:Name="ZoomStoryboard">
                <DoubleAnimation x:Name="ZoomAnimationX"
                                 Storyboard.TargetName="Workspace"
                                 Storyboard.TargetProperty="Canvas.RenderTransform.ScaleTransform.ScaleX"
                                 Duration="0:0:0.2"/>
                <DoubleAnimation x:Name="ZoomAnimationY"
                                 Storyboard.TargetName="Workspace"
                                 Storyboard.TargetProperty="Canvas.RenderTransform.ScaleTransform.ScaleY"
                                 Duration="0:0:0.2"/>
            </Storyboard>
        </Canvas.Resources>

with the following code:

_Zoom += (args.Delta / 7);
if (_Zoom < 0.15)
    _Zoom = 0.15;
ZoomAnimationX.To = _Zoom;
ZoomAnimationY.To = _Zoom;
ZoomStoryboard.Begin();
ZoomScale.Text = _Zoom.ToString("0.00") + "x";
_PreviousMousePosition = _CurrentMousePosition

However, the issue still arises that it is zooming out of the top-left corner, as opposed to sites like Google Maps where the zoom is "around" the mouse.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

错々过的事 2024-08-01 09:34:51

您需要根据鼠标位置使用加权平均值作为缩放中心。 换句话说,保留最新的缩放中心(或者如果还没有,只需将其设置为当前鼠标位置)并保留计算缩放中心的次数(第一次缩放后,该次数为 1) 。 每次重新计算缩放中心时,都会增加该变量。

示例代码如下 - deltaZoom 是缩放的程度,centerX 和 centerY 是当前缩放中心,ZoomSteps 是我们缩放的次数,mouseX 和 mouseY 是当前鼠标位置:

_Zoom += deltaZoom;
        if (_Zoom <= 0)
            _Zoom = 0.1;

        if (deltaZoom >= 0)
        {
            if (_ZoomSteps == -1)
            {
                _CenterX = 0;
                _CenterY = 0;
                _ZoomSteps = 0;
            }
            else
            {
                _CenterX = (_CenterX * Math.Abs(_ZoomSteps) + mouseX) / (Math.Abs(_ZoomSteps + 1));
                _CenterY = (_CenterY * Math.Abs(_ZoomSteps) + mouseY) / (Math.Abs(_ZoomSteps + 1));
                _ZoomSteps++;
            }
        }
        else
        {
            if (_ZoomSteps == 1)
            {
                _CenterX = 0;
                _CenterY = 0;
                _ZoomSteps = 0;
            }
            else
            {
                _CenterX = (_CenterX * Math.Abs(_ZoomSteps) - mouseX) / (Math.Abs(_ZoomSteps - 1));
                _CenterY = (_CenterY * Math.Abs(_ZoomSteps) - mouseY) / (Math.Abs(_ZoomSteps - 1));
                _ZoomSteps--;
            }
        }

        ZoomAnimationX.To = _Zoom;
        ZoomAnimationY.To = _Zoom;
        CenterAnimationX.To = Math.Abs(_CenterX);
        CenterAnimationY.To = Math.Abs(_CenterY);
        ZoomStoryboard.Begin();

已编辑,以便您可以放在下面1.0 缩放级别但仍然存在一些问题(ZoomStep = -1、0 或 1 有时会导致奇怪的抖动)。

You need to use a weighted average as the zoom center based on the mouse position. In other words, keep the latest zoom center (or if you don't have one yet just set it to the current mouse position) and keep the number of times the zoom center was calculated (after the first zoom, that would be 1). Than each time you recalculate the zoom center, increment that var.

Example Code Follows - deltaZoom is how much you're zooming, centerX and centerY are the current zoom center, ZoomSteps is the number of times we've zoomed, and mouseX and mouseY are the current mouse position:

_Zoom += deltaZoom;
        if (_Zoom <= 0)
            _Zoom = 0.1;

        if (deltaZoom >= 0)
        {
            if (_ZoomSteps == -1)
            {
                _CenterX = 0;
                _CenterY = 0;
                _ZoomSteps = 0;
            }
            else
            {
                _CenterX = (_CenterX * Math.Abs(_ZoomSteps) + mouseX) / (Math.Abs(_ZoomSteps + 1));
                _CenterY = (_CenterY * Math.Abs(_ZoomSteps) + mouseY) / (Math.Abs(_ZoomSteps + 1));
                _ZoomSteps++;
            }
        }
        else
        {
            if (_ZoomSteps == 1)
            {
                _CenterX = 0;
                _CenterY = 0;
                _ZoomSteps = 0;
            }
            else
            {
                _CenterX = (_CenterX * Math.Abs(_ZoomSteps) - mouseX) / (Math.Abs(_ZoomSteps - 1));
                _CenterY = (_CenterY * Math.Abs(_ZoomSteps) - mouseY) / (Math.Abs(_ZoomSteps - 1));
                _ZoomSteps--;
            }
        }

        ZoomAnimationX.To = _Zoom;
        ZoomAnimationY.To = _Zoom;
        CenterAnimationX.To = Math.Abs(_CenterX);
        CenterAnimationY.To = Math.Abs(_CenterY);
        ZoomStoryboard.Begin();

Edited so that you can drop below 1.0 zoom level but there are still some problems (ZoomStep = -1, 0 or 1 sometimes cause weird shakes).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文