Silverlight 3 - ScaleTransform 或其他放大画布的方法? [英] Silverlight 3 - ScaleTransform or other method to zoom in a Canvas?

查看:28
本文介绍了Silverlight 3 - ScaleTransform 或其他放大画布的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

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

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!

我已经设法使用动画平滑"缩放:

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>

使用以下代码:

_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.

推荐答案

您需要使用一个加权平均值作为基于鼠标位置的缩放中心.换句话说,保留最新的缩放中心(或者如果您还没有,则将其设置为当前鼠标位置)并保留计算缩放中心的次数(在第一次缩放之后,这将是 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.

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

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();

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

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).

这篇关于Silverlight 3 - ScaleTransform 或其他放大画布的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆