我试图让一个多边形完全从屏幕左侧移动,穿过屏幕,然后完全离开屏幕右侧,然后再移回。
我已经开始工作了。但是,出于某种原因,只要左边距变为负值,动画就会突然减慢。一旦左边距变为正,它就会再次加速。
为什么会这样?我怎么能阻止它?
以下是演示此内容的完整代码:
<Window x:Class="Geometry.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<PathGeometry x:Key="MyGeometry">
<PathGeometry.Figures>
<PathFigure>
<PathFigure.Segments>
<LineSegment Point="0.30,0" />
<LineSegment Point="0.70,1" />
<LineSegment Point="0.40,1" />
<LineSegment Point="0,0" />
</PathFigure.Segments>
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
<Storyboard x:Key="MovingAnimation">
<ThicknessAnimationUsingKeyFrames RepeatBehavior="1:0:0" FillBehavior="HoldEnd" Storyboard.TargetName="_path" Storyboard.TargetProperty="Margin" >
<DiscreteThicknessKeyFrame KeyTime="0:0:0" Value="-2.0,0,0,0" />
<LinearThicknessKeyFrame KeyTime="0:0:10" Value="1.0,0,0,0" />
<LinearThicknessKeyFrame KeyTime="0:0:20" Value="-2.0,0,0,0" />
</ThicknessAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard Storyboard="{StaticResource MovingAnimation}" ></BeginStoryboard>
</EventTrigger>
</Window.Triggers>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<Label>Margin:</Label>
<TextBlock Text="{Binding ElementName=_path, Path=Margin.Left, StringFormat={}{0:0.#}}" />
</StackPanel>
<Canvas Name="_canvas" Grid.Row="1">
<Border Margin="0" Width="1" Height="1" VerticalAlignment="Center" HorizontalAlignment="Center">
<Border.RenderTransform>
<ScaleTransform
ScaleX="{Binding ElementName=_canvas, Path=ActualWidth}"
ScaleY="{Binding ElementName=_canvas, Path=ActualHeight}"
CenterX="0"
CenterY="0">
</ScaleTransform>
</Border.RenderTransform>
<Path
Name="_path"
Fill="#CCCCFF"
Data="{StaticResource MyGeometry}"
Width="1.0"
Height="1.0"
>
</Path>
</Border>
</Canvas>
</Grid>
</Window>
答案 0 :(得分:4)
我没有解释为什么负边距动画缓慢,但我找到了解决方法。
我没有为Margin
的{{1}}设置动画,而是在Path
包含路径的X
对象上设置TranslateTransform
的{{1}}值。
我必须将Border
放在TranslateTransform
前面,以便在比例之前应用翻译。这使您可以在动画中使用与ScaleTransform
。
Margin
丑陋的部分是我无法找到一种快速方法将关键帧中的值直接应用于 <Storyboard x:Key="MovingAnimation">
<ThicknessAnimationUsingKeyFrames RepeatBehavior="1:0:0" Storyboard.TargetName="_blank" Storyboard.TargetProperty="Margin" >
<LinearThicknessKeyFrame KeyTime="0:0:0" Value="-1.5,0,0,0" />
<LinearThicknessKeyFrame KeyTime="0:0:10" Value="1,0,0,0" />
<LinearThicknessKeyFrame KeyTime="0:0:20" Value="-1.5,0,0,0" />
</ThicknessAnimationUsingKeyFrames>
</Storyboard>
的{{1}}属性,因此我欺骗并使用了元素绑定和占位符X
对象。
TranslateTransform
即使动画仍然被应用于Canvas
然后再通过元素绑定应用于 <StackPanel Grid.Row="0" Orientation="Horizontal" Margin="5">
<TextBlock Margin="0,0,5,0" Text="Margin.Left:"/>
<TextBlock Text="{Binding ElementName=_blank, Path=Margin.Left, StringFormat={}{0:0.#}}" />
</StackPanel>
<Canvas Name="_blank" /> <!--Placeholder object-->
<Canvas Name="_canvas" Grid.Row="1">
<Border Margin="0" Width="1" Height="1"
Name="_border"
VerticalAlignment="Center" HorizontalAlignment="Center">
<Border.RenderTransform>
<TransformGroup>
<TranslateTransform X="{Binding Margin.Left, ElementName=_blank}"/>
<ScaleTransform
ScaleX="{Binding ElementName=_canvas, Path=ActualWidth}"
ScaleY="{Binding ElementName=_canvas, Path=ActualHeight}"
CenterX="0"
CenterY="0">
</ScaleTransform>
</TransformGroup>
</Border.RenderTransform>
,负边距的延迟也就消失了。
我怀疑负边距延迟与Margin
中正在缩放的TranslateTransform
有关,但这是我的推测。
如果您可以找到将Path
值直接绑定到Border
的{{1}}属性的方法,那么这将使这种解决方法更加难看。
修改强> 弄清楚要使用的正确绑定:
KeyFrame
这消除了额外的画布占位符对象。
X
答案 1 :(得分:3)
动画保证金属性将触发额外的度量/排列传递,这反过来会对性能产生更大的影响(尽管在此示例中可能不会引人注意)。另一方面,“仅渲染”属性的动画不会触发布局重新排列,因此性能更友好。
请考虑一下,我想,你想做一些更简单的方法来做你想做的事情:
<Window x:Class="Geometry.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="518" Width="530">
<Window.Resources>
<PathGeometry x:Key="MyGeometry">
<PathGeometry.Figures>
<PathFigure>
<PathFigure.Segments>
<LineSegment Point="0.30,0" />
<LineSegment Point="0.70,1" />
<LineSegment Point="0.40,1" />
<LineSegment Point="0,0" />
</PathFigure.Segments>
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
<Storyboard x:Key="MovingAnimation">
<DoubleAnimationUsingKeyFrames RepeatBehavior="1:0:0" FillBehavior="HoldEnd" Storyboard.TargetName="_scaleTransform" Storyboard.TargetProperty="CenterX" >
<LinearDoubleKeyFrame KeyTime="0:0:0" Value="1.2" />
<LinearDoubleKeyFrame KeyTime="0:0:10" Value="-0.5" />
<LinearDoubleKeyFrame KeyTime="0:0:20" Value="1.2" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard Storyboard="{StaticResource MovingAnimation}" ></BeginStoryboard>
</EventTrigger>
</Window.Triggers>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<Label>Margin:</Label>
<TextBlock Text="{Binding ElementName=_scaleTransform, Path=CenterX, StringFormat={}{0:0.#}}" VerticalAlignment="Center" />
</StackPanel>
<!--
<Border Grid.Row="1" Margin="150" BorderBrush="Red" BorderThickness="1">
-->
<Grid Name="_canvas" Grid.Row="1">
<Path Name="_path" Fill="#CCCCFF" Data="{StaticResource MyGeometry}"
Width="1.0"
Height="1.0"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Path.RenderTransform>
<ScaleTransform x:Name="_scaleTransform"
ScaleX="{Binding ElementName=_canvas, Path=ActualWidth}"
ScaleY="{Binding ElementName=_canvas, Path=ActualHeight}"
CenterX="1.2"
CenterY="0.5">
</ScaleTransform>
</Path.RenderTransform>
</Path>
</Grid>
<!--
</Border>
-->
</Grid>
</Window>
答案 2 :(得分:1)
从目前为止的两个答案中可以清楚地看到,如果你想在屏幕上形成一个形状,请不要为边距设置动画。
另一个解决方案是,不是将多边形包裹在边框中并为边距设置动画,而是将其包裹在画布中并为左值设置动画。
将它包装在画布中:
<Canvas Name="_canvasFrame" Grid.Row="1">
<Canvas Margin="0" Width="1" Height="1">
<Canvas.RenderTransform>
<ScaleTransform
ScaleX="{Binding ElementName=_canvasFrame, Path=ActualWidth}"
ScaleY="{Binding ElementName=_canvasFrame, Path=ActualHeight}"
CenterX="0"
CenterY="0">
</ScaleTransform>
</Canvas.RenderTransform>
<Path
Name="_path"
Fill="#CCCCFF"
Data="{StaticResource MyGeometry}"
Width="1.0" Height="1.0"
>
</Path>
</Canvas>
</Canvas>
然后设置左值的动画:
<Storyboard x:Key="MovingAnimation">
<DoubleAnimationUsingKeyFrames
RepeatBehavior="1:0:0"
FillBehavior="HoldEnd"
Storyboard.TargetName="_path"
Storyboard.TargetProperty="(Canvas.Left)" >
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="-1.0" />
<LinearDoubleKeyFrame KeyTime="0:0:10" Value="1.0" />
<LinearDoubleKeyFrame KeyTime="0:0:20" Value="-1.0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>