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 )/ 缩放比
相关推荐
三千道应用题5 小时前
WPF&C#超市管理系统(4)入库管理
c#·wpf
freesheep72020 小时前
WPF使用PreviewTextInput事件限制用户输入
c#·wpf
c#上位机2 天前
wpf之ControlTemplate
wpf
小趴菜82274 天前
自定义View和动画学习记录 抓娃娃机View
android·kotlin·动画·自定义view
kyranhan4 天前
WPF,窗口拖动事件与窗口内控件点击事件
wpf
孟婆来包棒棒糖~5 天前
SpringCloude快速入门
分布式·后端·spring cloud·微服务·wpf
Humbunklung5 天前
C# WPF 实现读取文件夹中的PDF并显示其页数
pdf·c#·wpf·npoi·gemini·itext
wangnaisheng5 天前
【WPF】NumericUpDown的用法
wpf
步、步、为营5 天前
.NET 9 RC1 正式发布
.net·wpf
界面开发小八哥7 天前
界面组件DevExpress WPF中文教程:Grid - 如何过滤节点?
.net·wpf·界面控件·devexpress·ui开发