首页 > 解决方案 > c#中doubleAnimation完成后如何正确控制平移变换位置

问题描述

我使用以下代码在画布中间有一个椭圆:

var FixedCircle = new Ellipse
{
    Width = 25,
    Height = 25,
    Stroke = color,
    Fill = color,
    StrokeThickness = 3
};
var centerX = ActualWidth / 2;
var centerY = ActualHeight / 2;
FixedCircle.Margin = new Thickness(centerX, centerY, 1, 1);
Children.Add(FixedCircle);
InvalidateVisual();

我想为椭圆设置动画,使其从左侧回到中心(从中间点开始)。

我正在设置坐标(centerX,centerY)(0,centerY)作为起点和终点,我也在使用线条

Point oldPoint = FixedCircle.TransformToAncestor(this).Transform(new Point(centerX,centerY));
Point newPoint = FixedCircle.TransformToAncestor(this).Transform(new Point(0,centerY));

为了表明必须将变换设置为起始点g,我尝试删除它,但运动变得更糟并从底部开始,或者坐标(0,0)被视为中间而不是(ActualWidth / 2, ActualHeight / 2)我不想要的东西。

TranslateTransform trans = new TranslateTransform();
FixedCircle.RenderTransform = trans;
Point oldPoint = FixedCircle.TransformToAncestor(this).Transform(new Point(centerX,centerY));
Point newPoint = FixedCircle.TransformToAncestor(this).Transform(new Point(0,centerY));
var EndX = FixedCircle.Width / 2 + newPoint.X - oldPoint.X - (FixedCircle.Width);
var EndY = FixedCircle.Height / 2 + newPoint.Y - oldPoint.Y - (FixedCircle.Height);
var a1X = new DoubleAnimation(0, EndX, TimeSpan.FromSeconds(3));

a1X.Completed += (s, e) =>
{
    oldPoint = FixedCircle.TransformToAncestor(this).Transform(new Point(0, centerY));
    newPoint = FixedCircle.TransformToAncestor(this).Transform(new Point(centerX, centerY));
    EndX = FixedCircle.Width / 2 + newPoint.X - oldPoint.X - (FixedCircle.Width);
    EndY = FixedCircle.Height / 2 + newPoint.Y - oldPoint.Y - (FixedCircle.Height);
    var a2X = new DoubleAnimation(0, EndX, TimeSpan.FromSeconds(3));
    trans.BeginAnimation(TranslateTransform.XProperty, a2X);
};
trans.BeginAnimation(TranslateTransform.XProperty, a1X);

我得到的效果是椭圆正确地从中间向左走

在此处输入图像描述

然后是我的问题它从中间开始向右走,当我需要椭圆从左到中而不是从中间到右时

在此处输入图像描述

我错过了什么?

标签: c#wpfanimation

解决方案


以下代码从中间到左侧和后面运行重复的动画。它使用带有 EllipseGeometry 的路径,因为它是居中的(而不是像椭圆一样顶部/左对齐)。它也没有绘制任何笔划,只是将笔划粗细添加到椭圆的半径上。

var transform = new TranslateTransform(canvas.ActualWidth / 2, canvas.ActualHeight / 2);

var radius = 14;

var circle = new Path
{
    Data = new EllipseGeometry(new Point(), radius, radius),
    Fill = Brushes.White,
    RenderTransform = transform
};

canvas.Children.Add(circle);

var animation = new DoubleAnimation
{
    To = radius,
    Duration = TimeSpan.FromSeconds(3),
    AutoReverse = true,
    RepeatBehavior = RepeatBehavior.Forever
};

transform.BeginAnimation(TranslateTransform.XProperty, animation);

对于从中心点开始的从右到左并返回的重复动画,使用负的 BeginTime:

var transform = new TranslateTransform(
    canvas.ActualWidth - radius, canvas.ActualHeight / 2);

var animation = new DoubleAnimation
{
    To = radius,
    Duration = TimeSpan.FromSeconds(6),
    AutoReverse = true,
    RepeatBehavior = RepeatBehavior.Forever,
    BeginTime = TimeSpan.FromSeconds(-3)
};

推荐阅读