Pergunta

Eu preciso ser capaz de zoom in e out de uma tela usando a roda do mouse. I configurou com êxito os manipuladores de roda do mouse e atualmente estou usando um ScaleTransform para aplicar o zoom; no entanto, a escala não é feito de uma forma "intuitiva".

Eu estou tentando fazer o mesmo estilo de "zoom", como você pode ver na MultiScaleImage, o Google Maps / Earth ou Adobe Acrobat Reader - mas não com uma imagem, com um controle. A transição não precisa ser "suave" ou animado (a menos que seja uma abordagem mais fácil), mas as necessidades de funcionalidade a ser o mesmo.

Todos os pensamentos ou idéias seria muito apreciada e obrigado antecipadamente!

Edit: eu consegui "suavizar" o zoom utilizando animação:

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

com o seguinte código:

_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

No entanto, a questão ainda se coloca que está zumbindo com o canto superior esquerdo, ao contrário de sites como o Google Maps, onde o zoom está "em torno" do mouse.

Foi útil?

Solução

Você precisa usar uma média ponderada como o centro de zoom com base na posição do mouse. Em outras palavras, manter o centro da mais recente zoom (ou se você não tiver um ainda apenas configurá-lo para a posição atual do mouse) e manter o número de vezes que o centro de zoom foi calculada (após o primeiro zoom, que seria 1) . Que cada vez que você recalcular o centro de zoom, incremento que var.

Exemplo de código Segue - deltaZoom é quanto você está zoom, centerX e centerY são o centro de zoom atual, ZoomSteps é o número de vezes que já ampliada, e mouseX e mouseY são a posição atual do mouse:

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

editado para que você pode deixar cair abaixo do nível de 1,0 zoom, mas ainda existem alguns problemas (ZoomStep = -1, 0 ou 1, por vezes, causar shakes estranhas).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top