WPF缩放动画和平移动画叠加后会发生什么?

WPF实现边平移,边缩放的动画效果,它的平移坐标应该怎么计算?

我们可以写个小Demo测试下:

cs 复制代码
<Grid>
        <!-- 只做平移,不做缩放 -->
        <Border Height="100" Width="100" HorizontalAlignment="Left" VerticalAlignment="Top" Background="#7100FFFF">
            <Border.RenderTransform>
                <TransformGroup>
                    <TranslateTransform X="200" Y="100"/>
                </TransformGroup>
            </Border.RenderTransform>
        </Border>

        <!-- 1.5倍平移缩放后的对象 -->
        <Border Height="100" Width="100" HorizontalAlignment="Left" VerticalAlignment="Top" Background="#71FF0000">
            <Border.RenderTransform>
                <TransformGroup>
                    <TranslateTransform X="200" Y="100"/>
                    <ScaleTransform CenterX="50" CenterY="50" ScaleX="1.5" ScaleY="1.5"/>
                </TransformGroup>
            </Border.RenderTransform>
        </Border>
        
        <!-- 缩放后的大小和位置,通过Margin值,用于观察它的坐标位置 -->
        <Border Height="150" Width="150" HorizontalAlignment="Left" VerticalAlignment="Top" Background="#77777777" Margin="275,125,0,0">

        </Border>
    </Grid>

运行以上 demo代码后,我们可以看到他们的坐标值:

正常平移后,它的坐标是:(200,100)

平移缩放后,它的坐标是:(275,125)

我们来观察下这两组数据,做以下两种假设:

  1. 元素缩放后,平移的坐标值不会随着缩放的比例而发生变化。

  2. 元素缩放后,平移的坐标值,会跟随缩放的比例发生变化。

如果是第一种情况,我们来计算下,它平移后的值应该是多少:

cs 复制代码
//元素的宽度和高度值为100,缩放1.5倍之后为150。按左上角做平移后,它的理论值应该为:

//计算公式:目标位置 = 平移量  - (缩放后的宽高 - 原始宽高)/ 2
double offsetX = 200 - (150 - 100) / 2 = 175 ;
double offsetY = 100 - (150 -100) / 2 = 75 ;

通过上述计算得出的坐标点为:(175,75),显然跟实际结果不一致。

再来看下第二种假设:

cs 复制代码
//元素的宽度和高度值为100,缩放1.5倍之后为150。按左上角做平移后,它的理论值应该为:

//目标位置 = 平移量 * 缩放比 - (缩放后的宽高 - 原始宽高)/ 2
double offsetX = 200 * 1.5 - (150 - 100) / 2 = 275 ;
double offsetY = 100 * 1.5 - (150 - 100) / 2 = 125 ;

通过上述计算得出的坐标点为:(275,125),跟实际结果完全一致。

为了确定数据的准确性,我们可以增加几组数据做下测试对比,这里就省略了~

最终得出结论:平移和缩放两种变化叠加的时候,平移变换的偏移量也会跟着做缩放。

已知起始坐标和终止坐标的情况下,我们可以通过以下公式来计算偏移量:

cs 复制代码
        /// <summary>
        /// 获取缩放后所需要平移的值
        /// </summary>
        /// <param name="offset">缩放前需要平移的值</param>
        /// <param name="scale">缩放的倍数</param>
        /// <param name="elementWidthOrHeight">元素的宽或高</param>
        /// <returns></returns>
        private double GetScaleTranslateOffset(double offset, double scale, double elementWidthOrHeight)
        {
            //平移量 = ( 目标位置 + (缩放后的宽高 - 原始宽高)/ 2 )/ 缩放比
            //平移量 = ( 目标位置 + (缩放比 -1)* 宽高 / 2 )/ 缩放比
            return (offset + (scale - 1) * elementWidthOrHeight / 2) / scale;
        }

最后总结下:

cs 复制代码
   //目标位置 = 平移量 * 缩放比 - (缩放比 -1) * 宽高 / 2
   //平移量 = (目标位置 + (缩放比 -1) * 宽高 / 2 )/ 缩放比
相关推荐
TA远方1 小时前
【WPF】桌面程序使用谷歌浏览器内核CefSharp控件详解
wpf·浏览器·chromium·控件·cefsharp·cefsharp.wpf
Macbethad12 小时前
工业设备数据采集主站程序技术方案
wpf
关关长语21 小时前
HandyControl 3.5.x 版本 ListViewItem不显示问题
windows·wpf
Macbethad21 小时前
工业设备维护程序技术方案
wpf
Macbethad21 小时前
工业设备配方管理系统技术方案
wpf
喵叔哟1 天前
7.日志系统深入
wpf
清风徐来Groot1 天前
WPF布局之Grid
wpf
清风徐来Groot1 天前
WPF布局之WrapPanel
wpf
Macbethad1 天前
WPF工业设备工艺配方流程程序技术方案
wpf
清风徐来Groot1 天前
WPF布局之UniformGrid
wpf