C# 按属性沿路径移动对象
下面的代码借助双动画沿路径移动对象C# 按属性沿路径移动对象,c#,wpf,C#,Wpf,下面的代码借助双动画沿路径移动对象 <Window x:Class="TestsForTrafficSimulator.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.micros
<Window x:Class="TestsForTrafficSimulator.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TestsForTrafficSimulator"
mc:Ignorable="d"
Title="MainWindow" Height="700" Width="1050">
<Canvas x:Name="Main" Height="350 " Width="525">
<Canvas.Resources>
<Storyboard x:Key="Weeeee" RepeatBehavior="Forever">
<DoubleAnimationUsingPath Duration="0:0:3" Source="X" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.X)" Storyboard.TargetName="object_to_move" >
<DoubleAnimationUsingPath.PathGeometry>
<PathGeometry Figures="M0.83299852,-4.019 L0.83299852,0.6089829 L0.61794496,0.94214186 C-7.6701996,14.489389 -12.443,30.392629 -12.443001,47.403001 C-12.443,96.887715 27.948303,137.003 77.773499,137.003 C113.58536,137.003 144.52365,116.27938 159.09367,86.248303 L159.90265,84.471135 L380.931,84.471135 L380.931,86.871121 L160.63918,86.871121 L160.4838,87.217053 C145.62575,118.25356 114.07582,139.671 77.556,139.671 C26.745804,139.671 -14.444,98.212666 -14.444,47.071218 C-14.444,29.491346 -9.5768454,13.055669 -1.124851,-0.94513857 z"/>
</DoubleAnimationUsingPath.PathGeometry>
</DoubleAnimationUsingPath>
<DoubleAnimationUsingPath Duration="0:0:3" Source="Y" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.Y)" Storyboard.TargetName="object_to_move" >
<DoubleAnimationUsingPath.PathGeometry>
<PathGeometry Figures="M0.83299852,-4.019 L0.83299852,0.6089829 L0.61794496,0.94214186 C-7.6701996,14.489389 -12.443,30.392629 -12.443001,47.403001 C-12.443,96.887715 27.948303,137.003 77.773499,137.003 C113.58536,137.003 144.52365,116.27938 159.09367,86.248303 L159.90265,84.471135 L380.931,84.471135 L380.931,86.871121 L160.63918,86.871121 L160.4838,87.217053 C145.62575,118.25356 114.07582,139.671 77.556,139.671 C26.745804,139.671 -14.444,98.212666 -14.444,47.071218 C-14.444,29.491346 -9.5768454,13.055669 -1.124851,-0.94513857 z"/>
</DoubleAnimationUsingPath.PathGeometry>
</DoubleAnimationUsingPath>
</Storyboard>
</Canvas.Resources>
<Canvas.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource Weeeee}"/>
</EventTrigger>
</Canvas.Triggers>
<!-- Trajectory -->
<Path Data="M16.276999,1 L16.276999,5.627983 16.061945,5.9611419 C7.7738004,19.508389 3.0009999,35.41163 3.000999,52.422002 3.0009999,101.90672 43.392303,142.022 93.217499,142.022 129.02936,142.022 159.96765,121.29839 174.53767,91.267304 L175.34665,89.490136 396.375,89.490136 396.375,91.890122 176.08318,91.890122 175.9278,92.236054 C161.06975,123.27256 129.51982,144.69 93,144.69 42.189804,144.69 1,103.23167 1,52.090218 1,34.510346 5.8671546,18.07467 14.319149,4.0738615 z" Fill="#7F000000" Height="145.69" Canvas.Left="360.056" Stretch="Fill" Stroke="Red" StrokeThickness="2" Canvas.Top="236.648" Width="397.375"/>
<Ellipse x:Name="object_to_move" Fill="LightBlue" Height="30" Stroke="Black" Width="30" Canvas.Left="355" Canvas.Top="223.667" RenderTransformOrigin="0.5,0.5">
<Ellipse.RenderTransform>
<TransformGroup>
<TranslateTransform/>
</TransformGroup>
</Ellipse.RenderTransform>
</Ellipse>
</Canvas>
</Window>
但是,我正在搜索一个选项,以便通过属性沿此路径移动对象。例如,具有最小值=0
和最大值=100
的滑块可调节对象的“行驶距离”。这意味着当滑块位于0时,对象位于路径的开始处,在100时,对象位于路径的结束处。从开始到结束已经有一半了
我相信对于这个问题有一个相对简单的解决方案,但我似乎在互联网上搜索错误的关键字
编辑:
经过进一步的搜索,我很幸运,找到了可以用来获取路径上某个点的X和Y坐标的方法。我使用该点来平移对象
这是目前正在工作,但我仍然感兴趣的是是否有更好的解决方案a对代码做了一些修改,我只是这样做,滑块将跟踪椭圆到滑块的值。我没有包括连续动画。我将把所有需要的逻辑都留给你来整合 XAML:
<Canvas x:Name="Main" Height="350 " Width="525" Loaded="Main_OnLoaded">
<Canvas.Resources>
<Storyboard x:Key="Weeeee" RepeatBehavior="Forever" TargetName="object_to_move" Duration="0:0:3">
<DoubleAnimationUsingPath Duration="0:0:3" Source="X" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.X)" >
<DoubleAnimationUsingPath.PathGeometry>
<PathGeometry Figures="M0.83299852,-4.019 L0.83299852,0.6089829 L0.61794496,0.94214186 C-7.6701996,14.489389 -12.443,30.392629 -12.443001,47.403001 C-12.443,96.887715 27.948303,137.003 77.773499,137.003 C113.58536,137.003 144.52365,116.27938 159.09367,86.248303 L159.90265,84.471135 L380.931,84.471135 L380.931,86.871121 L160.63918,86.871121 L160.4838,87.217053 C145.62575,118.25356 114.07582,139.671 77.556,139.671 C26.745804,139.671 -14.444,98.212666 -14.444,47.071218 C-14.444,29.491346 -9.5768454,13.055669 -1.124851,-0.94513857 z"/>
</DoubleAnimationUsingPath.PathGeometry>
</DoubleAnimationUsingPath>
<DoubleAnimationUsingPath Duration="0:0:3" Source="Y" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.Y)" >
<DoubleAnimationUsingPath.PathGeometry>
<PathGeometry Figures="M0.83299852,-4.019 L0.83299852,0.6089829 L0.61794496,0.94214186 C-7.6701996,14.489389 -12.443,30.392629 -12.443001,47.403001 C-12.443,96.887715 27.948303,137.003 77.773499,137.003 C113.58536,137.003 144.52365,116.27938 159.09367,86.248303 L159.90265,84.471135 L380.931,84.471135 L380.931,86.871121 L160.63918,86.871121 L160.4838,87.217053 C145.62575,118.25356 114.07582,139.671 77.556,139.671 C26.745804,139.671 -14.444,98.212666 -14.444,47.071218 C-14.444,29.491346 -9.5768454,13.055669 -1.124851,-0.94513857 z"/>
</DoubleAnimationUsingPath.PathGeometry>
</DoubleAnimationUsingPath>
</Storyboard>
</Canvas.Resources>
<!-- Trajectory -->
<Slider x:Name="TestSlider" Width="200" Interval="1" Minimum="0" Maximum="1" ValueChanged="TestSlider_OnValueChanged"></Slider>
<TextBox Canvas.Top="40" Width="100" Text="{Binding Value, ElementName=TestSlider}"></TextBox>
<Path Data="M16.276999,1 L16.276999,5.627983 16.061945,5.9611419 C7.7738004,19.508389 3.0009999,35.41163 3.000999,52.422002 3.0009999,101.90672 43.392303,142.022 93.217499,142.022 129.02936,142.022 159.96765,121.29839 174.53767,91.267304 L175.34665,89.490136 396.375,89.490136 396.375,91.890122 176.08318,91.890122 175.9278,92.236054 C161.06975,123.27256 129.51982,144.69 93,144.69 42.189804,144.69 1,103.23167 1,52.090218 1,34.510346 5.8671546,18.07467 14.319149,4.0738615 z" Fill="#7F000000" Height="145.69" Canvas.Left="360.056" Stretch="Fill" Stroke="Red" StrokeThickness="2" Canvas.Top="236.648" Width="397.375"/>
<Ellipse x:Name="object_to_move" Fill="LightBlue" Height="30" Stroke="Black" Width="30" Canvas.Left="355" Canvas.Top="223.667" RenderTransformOrigin="0.5,0.5">
<Ellipse.RenderTransform>
<TransformGroup>
<TranslateTransform/>
</TransformGroup>
</Ellipse.RenderTransform>
</Ellipse>
变化:
- 必须将持续时间添加到故事板中李>
- 添加的滑块将在0-1的值范围内表示百分比李>
- 从XAML中删除了begin动画,并将事件处理程序添加到画布李>
private void TestSlider_OnValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
Storyboard sb = Main.FindResource("Weeeee") as Storyboard;
var ratio = sb.Duration.TimeSpan.TotalMilliseconds/2 * TestSlider.Value;
sb.Seek(object_to_move, new TimeSpan(0,0,0,0,(int)ratio), TimeSeekOrigin.BeginTime);
sb.Pause(object_to_move);
}
private void Main_OnLoaded(object sender, RoutedEventArgs e)
{
Storyboard sb = Main.FindResource("Weeeee") as Storyboard;
sb.Begin(object_to_move, true);
sb.Stop(object_to_move);
}
private void TestSlider\u OnValueChanged(对象发送方,RoutedPropertyChangedEventArgs e)
{
故事板sb=Main.FindResource(“Weeeee”)作为故事板;
var ratio=sb.Duration.TimeSpan.total毫秒/2*TestSlider.Value;
sb.Seek(对象对移动,新时间跨度(0,0,0,0,(int)比率),TimeSeekOrigin.BeginTime);
某人停顿(物体移动);
}
私有void Main_已加载(对象发送方,路由目标)
{
故事板sb=Main.FindResource(“Weeeee”)作为故事板;
某人开始(物体移动,正确);
某人停下来(反对移动);
}
注:
- 需要从代码调用
方法,因为需要设置true标志。这将设置Begin
标志。我停止它只是为了不运行连续动画李>iscontroller
- 我计算滑块与总持续时间的比率来确定位置。根据需要编辑此文件李>
方法是将动画设置为给定的.Seek
的神奇之处李>时间跨度
- I
,因为动画将在暂停
调用后启动李>搜索
这可以让你看起来更花哨,但它应该能给你所需要的信息来完成你所寻找的 这是一个有效的解决方案!谢谢你的贡献。然而,这与我的方法非常相似,感觉有点像黑客,因为我根本不想使用动画——这只是第一种方法。