Pregunta

Estoy escribiendo una aplicación de WPF que tiene un zoom y capacidad de bandeja, pero lo que yo quiero poner en práctica también es la capacidad de zoom y panorámica "de forma automática" (a través de un clic de botón).

Tengo los métodos, todos ellos definidos para hacer zoom y pan, pero estoy teniendo problemas para establecer la aplicación de los deseados coordenadas X / Y para la toma panorámica.

Básicamente, sé que quiero que el control se centra en un nivel de zoom deseado (digamos ampliada en tiempos 6X), pero el punto de destino paneo no es el punto central del control porque después del zoom, su sido reducido.

¿Alguien sabe una forma de calcular la posición X / Y deseada para desplazarse a, teniendo en cuenta la función de zoom, así? No acabo escalo el destino deseado Point? Eso no parece funcionar para mí ...

Muchas gracias

Editar - Completa -

Aquí es lo que tengo ahora que está funcionando muy bien:)

<Canvas x:Name="LayoutRoot" Background="{DynamicResource WindowBackground}" Width="1024" Height="768">
    <Canvas x:Name="ProductCanvas" Width="1024" Height="768">
        <Canvas.RenderTransform>
            <TransformGroup>
                <ScaleTransform/>
                <SkewTransform/>
                <RotateTransform/>
                <TranslateTransform />
            </TransformGroup>
        </Canvas.RenderTransform>
        <Rectangle x:Name="r1" Fill="White" Stroke="Black" Width="180" Height="103.5" Canvas.Left="131.5" Canvas.Top="121.5" MouseDown="r1_MouseDown"/>
        <Rectangle x:Name="r2" Fill="#FF942222" Stroke="Black" Width="180" Height="103.5" Canvas.Left="617.5" Canvas.Top="121.5" MouseDown="r2_MouseDown"/>
        <Rectangle x:Name="r3" Fill="#FF2B1E9F" Stroke="Black" Width="180" Height="103.5" Canvas.Left="131.5" Canvas.Top="408" MouseDown="r3_MouseDown"/>
        <Rectangle x:Name="r4" Fill="#FF1F6E1D" Stroke="Black" Width="180" Height="103.5" Canvas.Left="617.5" Canvas.Top="408" MouseDown="r4_MouseDown"/>
    </Canvas>
  </Canvas>

---- ---- C #

    private void r1_MouseDown(object sender, MouseButtonEventArgs e1)
    {
        Rect bounds = r1.TransformToAncestor(ProductCanvas).TransformBounds(new Rect(0, 0, r1.ActualWidth, r1.ActualHeight));
        ZoomInAndPan(5, new Point(bounds.TopLeft.X + (bounds.Width / 2), bounds.TopLeft.Y + (bounds.Height / 2)));
    }

    private void r2_MouseDown(object sender, MouseButtonEventArgs e1)
    {
        Rect bounds = r2.TransformToAncestor(ProductCanvas).TransformBounds(new Rect(0, 0, r2.ActualWidth, r2.ActualHeight));
        ZoomInAndPan(5, new Point(bounds.TopLeft.X + (bounds.Width / 2), bounds.TopLeft.Y + (bounds.Height / 2)));
    }

    private void r3_MouseDown(object sender, MouseButtonEventArgs e1)
    {
        Rect bounds = r3.TransformToAncestor(ProductCanvas).TransformBounds(new Rect(0, 0, r3.ActualWidth, r3.ActualHeight));
        ZoomInAndPan(5, new Point(bounds.TopLeft.X + (bounds.Width / 2), bounds.TopLeft.Y + (bounds.Height / 2)));
    }

    private void r4_MouseDown(object sender, MouseButtonEventArgs e1)
    {
        Rect bounds = r4.TransformToAncestor(ProductCanvas).TransformBounds(new Rect(0, 0, r4.ActualWidth, r4.ActualHeight));
        ZoomInAndPan(5, new Point(bounds.TopLeft.X + (bounds.Width/2), bounds.TopLeft.Y + (bounds.Height/2)));
    }

    public void ZoomInAndPan(double zoomTo, Point translateTarget)
    {
        var group = (ProductCanvas.RenderTransform as TransformGroup);

        var zoomTransform = group.Children[0] as ScaleTransform;
        var translateTransform = group.Children[3] as TranslateTransform;

        Point center = new Point(512, 384);

        destinationPoint.X *= newScale;
        destinationPoint.Y *= newScale;

        var deltaX = center.X - (translateTarget.X);
        var deltaY = center.Y - (translateTarget.Y);

        translateTransform.BeginAnimation(TranslateTransform.XProperty, CreateZoomAnimation(deltaX));
        translateTransform.BeginAnimation(TranslateTransform.YProperty, CreateZoomAnimation(deltaY));

        zoomTransform.BeginAnimation(ScaleTransform.ScaleXProperty, CreateZoomAnimation(zoomTo));
        zoomTransform.BeginAnimation(ScaleTransform.ScaleYProperty, CreateZoomAnimation(zoomTo));
    }

    private DoubleAnimation CreateZoomAnimation(double toValue)
    {
        var da = new DoubleAnimation(toValue, new Duration(TimeSpan.FromMilliseconds(700)))
        {
            AccelerationRatio = 0.1,
            DecelerationRatio = 0.9
        };

        return da;
    }
¿Fue útil?

Solución

Estamos hablando de una transformación -. Una sartén y una escala

Usted puede hacer esto un par de maneras diferentes, pero dado que está utilizando WPF, ¿hay alguna razón no se puede simplemente utilizar los RenderTransforms?

var pointClicked = (where user clicked)
var myWindow = (whatever your window is);

myWindow.RenderTransform = new TransformGroup();
var pan = new TranslateTransform(pointClicked.X, pointClicked.Y);
var scale = new ScaleTransform(6.0,6.0);
myWindow.RenderTransform.Children.Add(pan);
myWindow.RenderTransform.Children.Add(scale);

Si no desea ir por ese camino, que tiene que hacer la transformación 2D "a mano", pero hacer la sartén primero, y luego la escala. Las transformaciones no son por lo general communitive; obtendrá resultados erróneos si lo ponen en un orden diferente.

Otros consejos

Inicialmente, el visor está en (0,0) y la imagen y el visor es de tamaño X por Y. desea escalar el tamaño por un factor de ampliación, m para que sus imágenes es de tamaño m X por m Y, pero la ventana gráfica (la parte que está mostrando) sigue siendo un rectángulo del tamaño de X por Y, colocado en (0,0) en la imagen. Así que hay que mover la ventana de observación.

Si la imagen es ahora m X por m Y, se pueden encontrar los puntos medios de la división de cada dos. A continuación, puede restar la mitad del tamaño de la ventana para obtener la esquina superior izquierda. Algo así como (m X / 2 - X / 2, m Y / 2 - Y / 2).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top