我有一个故事板,我正在制作一个矩形,像MPH汽车仪表中的针一样向上移动。所以,我让它从0变为60,我希望能够在变化时获得当前值,这样我就可以使用该值来制作数字仪表。
如何从双动画的开头到结尾获取当前值?我有这样的事情:
DoubleAnimation da = new DoubleAnimation();
da.Duration = new Duration(TimeSpan.FromSeconds(5));
da.From = 0;
da.To = 60;
RotateTransform rt = new RotateTransform();
rt.CenterX = 35;
rt.CenterY = 0;
rec3.RenderTransform = rt;
rt.BeginAnimation(RotateTransform.AngleProperty, da);
当它向上旋转矩形时,我试图获得该角度,但它只是返回零。
答案 0 :(得分:3)
你必须做错事,考虑这个例子:
<Rectangle Width="100" Height="10" Fill="Red" HorizontalAlignment="Left" RenderTransformOrigin="1,0.5">
<Rectangle.RenderTransform>
<RotateTransform x:Name="rt" />
</Rectangle.RenderTransform>
</Rectangle>
<TextBlock Text="{Binding ElementName=rt, Path=Angle}" />
rt.BeginAnimation(RotateTransform.AngleProperty, new DoubleAnimation(0, 60, TimeSpan.FromSeconds(1), FillBehavior.HoldEnd));
它显示的值很好。
如果您将rt.Angle
分配给某个变量,该变量将在该时间点具有变换角度的值,那么它将与rt.Angle
同时不会更改属性。
如果您不熟悉我在上述代码中使用的数据绑定,您可能需要查看overview。
答案 1 :(得分:2)
不确定您面临的问题到底是什么,但我刚检查过,此代码会显示当前的角度:
RotateTransform rt = new RotateTransform();
private void button1_Click(object sender, RoutedEventArgs e)
{
DoubleAnimation da = new DoubleAnimation();
da.Duration = new Duration(TimeSpan.FromSeconds(10));
da.From = 0;
da.To = 60;
rt.CenterX = 35;
rt.CenterY = 0;
rectangle1.RenderTransform = rt;
rt.BeginAnimation(RotateTransform.AngleProperty, da);
}
private void button2_Click(object sender, RoutedEventArgs e)
{
var x = rt.Angle; // x will have the value of current angle
}
[编辑]
如果您需要从另一个类访问私有rt.Angle,您可以通过以下属性公开它:
public Double CurrentAngle
{
get { return rt.Angle; }
}
答案 2 :(得分:0)
晚上好。我有一个类似的问题,但在动画动画期间获取元素的位置。我用时间解决了这个问题。此方法基于知道动画开始后经过的时间。比方说,我们有这个元素的类代码:
Location = new Point(100, 100);
// set animations
var moveTime = 5000.0;
var function = new SineEase { EasingMode = EasingMode.EaseInOut };
var shift = new Point(1000, 700);
var locationAnimationX = new DoubleAnimation
{
Duration = TimeSpan.FromMilliseconds(moveTime),
To = shift .X,
EasingFunction = function
};
var locationAnimationY = new DoubleAnimation
{
Duration = TimeSpan.FromMilliseconds(moveTime),
To = shift .Y,
EasingFunction = function
};
// attach animations to this element and its properties
Storyboard.SetTarget(locationAnimationX, this);
Storyboard.SetTargetProperty(locationAnimationX, "(UIElement.RenderTransform).(CompositeTransform.TranslateX)");
Storyboard.SetTarget(locationAnimationY, this);
Storyboard.SetTargetProperty(locationAnimationY, "(UIElement.RenderTransform).(CompositeTransform.TranslateY)");
// create storyboard and start animation of move
var moveStory = new Storyboard();
moveStory.Children.Add(locationAnimationX);
moveStory.Children.Add(locationAnimationY);
moveStory.Begin();
var startTime = DateTime.Now;
例如,我们必须在一段时间后知道当前位置。所以,让我们开始。
var elapsedTime = DateTime.Now.Subtract(startTime).TotalMilliseconds;
var ratio = elapsedTime / moveTime;
var funcCurrentValue = function.Ease(ratio);
var currentShift = new Point(shift.X * funcCurrentValue, shift.Y * funcCurrentValue);
最后,当前位置由:
给出var currentLocation = new Point(Location.X + currentShift.X, Location.Y + currentShift.Y);
答案 3 :(得分:0)
尽管这里有一些宣传海报,我还注意到在动画进行过程中很难访问动画属性的当前值。这是一个很好的解决方案,我已经习惯使用WPF动画在我的模型中随时间插值。
public class AnimatedDoubleValue : UIElement
{
public event PropertyChangedEventHandler PropertyChanged;
private void FirePropertyChanged(string name)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
private double _value_cache; // this stores the current animated value!
public double Value
{
get { return (double)GetValue(ValueProperty); }
set
{
if (_value_cache == value)
return;
_value_cache = value;
SetValue(ValueProperty, value);
FirePropertyChanged("Value");
}
}
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(double), typeof(AnimatedDoubleValue), new UIPropertyMetadata(0.0, ValuePropertyChanged));
private static void ValuePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var self = (AnimatedDoubleValue)sender;
var value = (double)e.NewValue;
self.UpdateValue(value);
}
private void UpdateValue(double value)
{
_value_cache = value;
FirePropertyChanged("Value");
}
}
如果我理解正确,OP希望重复使用WPF动画工具进行模拟。这不是一个坏主意,因为根据经过的时间内插值并非完全无关紧要。
甚至不必将此AnimatedDoubleValue链接到WPF窗口小部件树。它可以用于获取动画值的更新。使用方式如下:
var doubleValue = new AnimatedDoubleValue();
var animation=new DoubleAnimation() { From=0, To=100, Duration=TimeSpan.FromSeconds(1) };
animation.SetValue(Storyboard.DesiredFrameRateProperty, 30);
doubleValue.BeginAnimation(AnimatedDoubleValue.ValueProperty, animation, HandoffBehavior.SnapshotAndReplace);
现在,您可以在doubleValue上收听PropertyChanged事件,也可以随时访问其Value属性。