我有一个包含两个Storyboard
动画的WPF RepeatBehavior=Forever
(DoubleAnimationUsingPath
}。这些动画跟踪一个圆形路径,我通过添加EllipseGeometry
创建。一个动画用于控制X位置,另一个动画用于控制另一个使用圆形路径进行轨道运动的物体的Y位置。
动画始终沿顺时针方向跟随路径,并始终从圆圈右侧的中间开始。我需要强制动画反向播放(即沿路径逆时针)。理想情况下,我也希望能够控制起始位置,但现在这不是必需的。
动画上的AutoReverse
属性做了我想要的,但显然它在顺时针和逆时针之间交替 - 我需要动画循环,总是在逆时针方向。
我还尝试使用ScaleTransform
和ScaleX = -1
来翻转椭圆,希望这会有所帮助 - 但事实并非如此。
有没有办法迫使DoubleAnimationUsingPath
遵循路径上的特定方向?
答案 0 :(得分:1)
您可以使用相同的坐标切换两条路径,但反向。这是一个使用MatrixAnimationUsingPath
的示例,其中当UI元素加载时动画方向为cw,当鼠标指针进入蓝色矩形时,动画方向变为ccw。
<Canvas ClipToBounds="False" Width="400" Height="400">
<Path StrokeThickness="10" StrokeDashArray="" StrokeDashCap="Flat" StrokeDashOffset="0" StrokeStartLineCap="Flat" StrokeEndLineCap="Flat" StrokeLineJoin="Miter" StrokeMiterLimit="10" Stroke="#000000">
<Path.Data>
<PathGeometry Figures="M 150,250 C 150,120 300,120 300,250 C 300,390 150,390 150,250 Z" />
</Path.Data>
</Path>
<Rectangle Fill="Blue" RenderTransformOrigin="0.5,0.5" Width="10" Height="10" Margin="-5">
<Rectangle.RenderTransform>
<TransformGroup>
<MatrixTransform x:Name="tt">
<MatrixTransform.Matrix>
<Matrix />
</MatrixTransform.Matrix>
</MatrixTransform>
</TransformGroup>
</Rectangle.RenderTransform>
<Rectangle.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard>
<MatrixAnimationUsingPath Duration="0:0:05" Storyboard.TargetName="tt"
Storyboard.TargetProperty="Matrix"
AutoReverse="False"
DoesRotateWithTangent="True"
RepeatBehavior="Forever"
>
<MatrixAnimationUsingPath.PathGeometry>
<PathGeometry Figures="M 150,250 C 150,120 300,120 300,250 C 300,390 150,390 150,250 Z">
</PathGeometry>
</MatrixAnimationUsingPath.PathGeometry>
</MatrixAnimationUsingPath>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="FrameworkElement.MouseEnter">
<BeginStoryboard>
<Storyboard>
<MatrixAnimationUsingPath Duration="0:0:05" Storyboard.TargetName="tt"
Storyboard.TargetProperty="Matrix"
AutoReverse="False"
DoesRotateWithTangent="True"
RepeatBehavior="Forever"
>
<MatrixAnimationUsingPath.PathGeometry>
<PathGeometry Figures="M 150,250 C 150,390 300,390 300,250 C 300,120 150,120 150,250 Z" >
</PathGeometry>
</MatrixAnimationUsingPath.PathGeometry>
</MatrixAnimationUsingPath>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
答案 1 :(得分:1)
DoubleAnimationUsingPath
的替代方案是提供正弦值的自定义动画。它具有Amplitude
属性,可控制振幅,其符号也可控制窦动画的方向。还有一个StartAngle
属性控制动画开始的角度。
public class SinusAnimation : DoubleAnimationBase
{
public static readonly DependencyProperty AmplitudeProperty =
DependencyProperty.Register(
"Amplitude", typeof(double), typeof(SinusAnimation));
public static readonly DependencyProperty StartAngleProperty =
DependencyProperty.Register(
"StartAngle", typeof(double), typeof(SinusAnimation));
public double Amplitude
{
get { return (double)GetValue(AmplitudeProperty); }
set { SetValue(AmplitudeProperty, value); }
}
public double StartAngle
{
get { return (double)GetValue(StartAngleProperty); }
set { SetValue(StartAngleProperty, value); }
}
protected override double GetCurrentValueCore(double defaultOriginValue,
double defaultDestinationValue, AnimationClock animationClock)
{
var result = defaultOriginValue;
var p = animationClock.CurrentProgress;
if (p.HasValue)
{
result = Amplitude * Math.Sin(
p.Value * Math.PI * 2d + StartAngle * Math.PI / 180d);
}
return result;
}
protected override Freezable CreateInstanceCore()
{
return new SinusAnimation();
}
}
这是一个简单的XAML,可以创建一个小蓝圈的圆周运动。通过不同的振幅,它也可以创建椭圆轨迹,并且通过不同的StartAngles也可以创建各种Lissajous数字。
<Canvas Margin="200">
<Path Fill="Blue">
<Path.Data>
<EllipseGeometry RadiusX="10" RadiusY="10"/>
</Path.Data>
<Path.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard Duration="0:0:2" RepeatBehavior="Forever">
<local:SinusAnimation
Storyboard.TargetProperty="(Canvas.Left)"
Amplitude="100"
Duration="0:0:2" RepeatBehavior="Forever"/>
<local:SinusAnimation
Storyboard.TargetProperty="(Canvas.Top)"
Amplitude="100" StartAngle="90"
Duration="0:0:2" RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Path.Triggers>
</Path>
</Canvas>
编辑:为了反转DoubleAnmationUsingPath
,您只需将使用过的PathGeometry的Transform属性设置为适当的ScaleTransform:
<PathGeometry x:Key="path">
<PathGeometry.Transform>
<ScaleTransform ScaleX="-1"/>
</PathGeometry.Transform>
...
</PathGeometry>