Как вы можете рассчитать координату X / Y, чтобы увеличить

StackOverflow https://stackoverflow.com/questions/2375318

Вопрос

Я пишу приложение WPF, которое имеет масштабирование и способность PAN, но то, что я хочу также реализовать, - это возможность увеличить масштаб и сковороду «автоматически» (через кнопку щелчка).

У меня есть методы, которые все определены для масштабирования и сковородок, но у меня проблемы с тем, что у меня проблемы с тем, что приложению приложений желаемых координат X / Y для панорамирования.

В принципе, я знаю, что я хочу, чтобы контроль был сосредоточен на желаемом уровне масштабирования (скажем, увеличен в 6x раз), но точка назначения панорамирования не является центральной точкой контроля, потому что после масштабирования его масштабировалось.

Кто-нибудь знает способ расчета желаемого положения X / Y для PAN, с учетом масштабирования? Я просто масштабирую желаемую точку назначения? Похоже, для меня не работает ...

Большое спасибо

Редактировать - Завершено -

Вот теперь то, что у меня есть, что работает просто хорошо :)

<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;
    }
Это было полезно?

Решение

Вы говорите о трансформации - сковороду и масштабах.

Вы можете сделать это пару разных способов, но так как вы используете WPF, есть ли причина, по которой вы не можете просто использовать 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);

Если вы не хотите проходить этот маршрут, вам нужно сделать 2D преобразование «вручную»: но сначала выполните сковороду, затем масштаб. Преобразования обычно не взаимодействуют; Вы получите неправильные результаты, если вы делаете их в другом порядке.

Другие советы

Первоначально ваша просмотр входит в (0,0), и как изображение, так и изображение VIVES в размере X по Y. Вы хотите масштабировать размер некоторого коэффициента увеличения, м, чтобы ваши изображения были размером м.Х по М.Y, но ваш вид просмотра (деталь, которую вы показываете), по-прежнему является прямоугольником размера X по y, расположенными в (0,0) на изображении. Таким образом, вам нужно переместить порт просмотра.

Если ваше изображение сейчас mХ по М.Y, вы можете найти средние точки, разделив каждый на два. Затем вы можете вычесть половину размера Viewport, чтобы получить верхний левый угол. Что-то вроде (мХ / 2 - х / 2, мY / 2 - Y / 2).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top