11

マウスホイールを使用してキャンバスをズームインおよびズームアウトできるようにする必要があります。マウス ホイール ハンドラーを正常にセットアップし、現在 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 マップなどのサイトとは対照的に、左上隅からズームアウトしているという問題は依然として発生します。

4

1 に答える 1

10

マウスの位置に基づいて、ズームの中心として加重平均を使用する必要があります。つまり、最新のズームセンターを保持し(または、ズームセンターがまだない場合は、現在のマウス位置に設定します)、ズームセンターが計算された回数を保持します(最初のズーム後、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は時々奇妙な揺れを引き起こします)。

于 2009-06-23T14:15:10.800 に答える