代码之家  ›  专栏  ›  技术社区  ›  Puppy

WPF中奇怪的缩放问题

  •  2
  • Puppy  · 技术社区  · 15 年前

            foreach (UIElement element in canvas1.Children)
            {
                Point p = e.MouseDevice.GetPosition(element);
                Matrix m = element.RenderTransform.Value;
                if (e.Delta > 0)
                    m.ScaleAt(1.1, 1.1, p.X, p.Y);
                else
                    m.ScaleAt(1 / 1.1, 1 / 1.1, p.X, p.Y);
                element.RenderTransform = new MatrixTransform(m);
            }
    

    到底发生了什么?

    我意识到我最初的问题文本并没有那么清晰。我从鼠标原点开始缩放,所以你将鼠标移到我的示例文本对象对的左侧,滚动滚轮,它们会放大或缩小,并以完美的方式在屏幕上移动。但是如果你将鼠标移到对象另一边的最右边,并尝试滚动,那么它们的行为就像鼠标在它们中间一样——也就是说,它们在屏幕上不移动的情况下进行放大和缩小。

    1 回复  |  直到 15 年前
        1
  •  6
  •   Quartermeister    15 年前

    使用ScaleAt创建转换时,也在创建转换。例如,如果鼠标指针位于元素左侧100像素处,则您将按1.1的比例缩放它,并将其向右移动10像素。下一次代码运行时,您也将缩放该转换,因此除了新的转换之外,还要将其向右移动1个像素。

    foreach (UIElement element in canvas1.Children)
    {
        Point p = e.MouseDevice.GetPosition(element);
        Matrix m = element.RenderTransform.Value;
        Matrix m2 = m;
        m2.Translate(-m.OffsetX, -m.OffsetY);
        if (e.Delta > 0)
            m2.ScaleAt(1.1, 1.1, p.X, p.Y);
        else
            m2.ScaleAt(1 / 1.1, 1 / 1.1, p.X, p.Y);
        m2.Translate(m.OffsetX, m.OffsetY);
        element.RenderTransform = new MatrixTransform(m2);
    }
    

    一个类似的选项是始终从RenderTransform中移除缩放并将其编码为画布。左边以及帆布。上衣:

    foreach (UIElement element in canvas1.Children)
    {
        Point p = e.MouseDevice.GetPosition(element);
        Matrix m = element.RenderTransform.Value;
        if (e.Delta > 0)
            m.ScaleAt(1.1, 1.1, p.X, p.Y);
        else
            m.ScaleAt(1 / 1.1, 1 / 1.1, p.X, p.Y);
        Canvas.SetLeft(element, Canvas.GetLeft(element) + m.OffsetX);
        Canvas.SetTop(element, Canvas.GetTop(element) + m.OffsetY);
        m.Translate(-m.OffsetX, -m.OffsetY);
        element.RenderTransform = new MatrixTransform(m);
    }
    

    更新:事实上,我想我错过了更大的,相关的影响。因为你是在旧的比例尺之后应用新的比例尺,所以p.X和p.Y的翻译会在不应该的时候被缩放。当标度很大时,这将是一个很大的误差(而我上面提到的误差总是10%的误差)。

    尝试使用 ScaleAtPrepend

    foreach (UIElement element in canvas1.Children)
    {
        Point p = e.MouseDevice.GetPosition(element);
        Matrix m = element.RenderTransform.Value;
        if (e.Delta > 0)
            m.ScaleAtPrepend(1.1, 1.1, p.X, p.Y);
        else
            m.ScaleAtPrepend(1 / 1.1, 1 / 1.1, p.X, p.Y);
        Canvas.SetLeft(element, Canvas.GetLeft(element) + m.OffsetX);
        Canvas.SetTop(element, Canvas.GetTop(element) + m.OffsetY);
        m.Translate(-m.OffsetX, -m.OffsetY);
        element.RenderTransform = new MatrixTransform(m);
    }