Silverlight 3 - ScaleTransform ou outro método para fazer zoom e uma tela?
-
06-07-2019 - |
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.
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).