日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

WPF路径动画(动态逆向动画)

發(fā)布時間:2025/4/16 asp.net 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WPF路径动画(动态逆向动画) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

WPF 中的Path.Data 不再多介紹,M開始坐標(biāo)點 C弧度坐標(biāo)點 L 直線坐標(biāo)點

<Path x:Name="path0" Data="M 10,100 C 35,0 135,0 160,100 180,190 285,200 310,100" Height="135.32" Stretch="Uniform" Stroke="#FF61E70A" StrokeThickness="2" HorizontalAlignment="Center" VerticalAlignment="Center" />

?

<Path x:Name="path0" Data="M95,50 L324.67997,50 324.67997,119.67997 234.67998,119.67997 234.67998,184.68002 344.67999,184.68002 394.68,134.67999 C394.68,134.67999 394.68,189.68005 394.68,129.68002 394.68,69.679984 434.68002,89.679985 434.68002,89.679985L477.18005,132.18003 477.18005,164.68004 419.68006,164.6800" Height="135.32" Stretch="Uniform" Stroke="#FF61E70A" StrokeThickness="2" HorizontalAlignment="Center" VerticalAlignment="Center" />

個人寫了關(guān)于Path.Data數(shù)據(jù)反向,意思就是把Path的數(shù)據(jù)逆轉(zhuǎn),但是圖形是沒有變化的

Xaml代碼如下:

<Window x:Class="WPFPathReverse.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:WPFPathReverse"mc:Ignorable="d"Title="MainWindow" Height="600" Width="500"><Grid><Grid.RowDefinitions><RowDefinition Height="50"></RowDefinition><RowDefinition></RowDefinition><RowDefinition></RowDefinition></Grid.RowDefinitions><StackPanel Orientation="Horizontal"><Button Content="正向動畫" Width="80" Margin="5" Click="btnPositive_Click"></Button><Button Content="反向動畫" Width="80" Margin="5" Click="btnRevPositive_Click"></Button></StackPanel><Canvas Grid.Row="1" ><Path x:Name="path0" Data="M1,1 L230.67997,1 230.67997,70.67997 140.67998,70.67997 140.67998,135.68002 300.68,85.67999 C300.68,85.67999 300.68,140.68005 300.68,80.68002 300.68,20.679984 340.68002,40.679985 340.68002,40.679985 L383.18005,83.18003 383.18005,115.68004 325.68006,115.68" Height="136.68" Stretch="None" Stroke="#FF61E70A" StrokeThickness="2" Width="384.18" /></Canvas><Canvas x:Name="canvas" Grid.Row="2"></Canvas></Grid> </Window> View Code

Code代碼如下

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes;namespace WPFPathReverse {/// <summary>/// MainWindow.xaml 的交互邏輯/// </summary>public partial class MainWindow : Window{public MainWindow(){InitializeComponent();this.Loaded += MainWindow_Loaded;}private void MainWindow_Loaded(object sender, RoutedEventArgs e){string data = this.path0.Data.ToString();var result = ConvertReverseData(data);Path newpath = new Path();newpath.Data = PathGeometry.CreateFromGeometry(Geometry.Parse(result));newpath.HorizontalAlignment = HorizontalAlignment.Center;newpath.VerticalAlignment = VerticalAlignment.Center;newpath.Stretch = this.path0.Stretch;newpath.Stroke = new SolidColorBrush(Colors.Red);newpath.StrokeThickness = 2;newpath.Width = this.path0.Width;newpath.Height = this.path0.Height;canvas.Children.Add(newpath);}/// <summary>/// 反向Data數(shù)據(jù)/// </summary>/// <param name="data"></param>/// <returns></returns>string ConvertReverseData(string data){data = data.Replace("M", "").Replace(" ", "/");Regex regex = new Regex("[a-z]", RegexOptions.IgnoreCase);MatchCollection mc = regex.Matches(data);//item1 從上一個位置到當(dāng)前位置開始的字符 (match.Index=原始字符串中發(fā)現(xiàn)捕獲的子字符串的第一個字符的位置。)//item2 當(dāng)前發(fā)現(xiàn)的匹配符號(L C Z M)List<Tuple<string, string>> tmpList = new List<Tuple<string, string>>();int curPostion = 0;for (int i = 0; i < mc.Count; i++){Match match = mc[i];if (match.Index != curPostion){string str = data.Substring(curPostion, match.Index - curPostion);tmpList.Add(new Tuple<string, string>(str, match.Value));}curPostion = match.Index + match.Length;if (i + 1 == mc.Count)//last {tmpList.Add(new Tuple<string, string>(data.Substring(curPostion), match.Value));}}//char[] spChar = new char[2] { 'C', 'L' };//var tmpList = data.Split(spChar);List<string[]> spList = new List<string[]>();for (int i = 0; i < tmpList.Count; i++){var cList = tmpList[i].Item1.Split('/');spList.Add(cList);}List<string> strList = new List<string>();for (int i = spList.Count - 1; i >= 0; i--){string[] clist = spList[i];for (int j = clist.Length - 1; j >= 0; j--){if (j == clist.Length - 2)//對于第二個元素增加 L或者C的標(biāo)識 {var pointWord = tmpList[i - 1].Item2;//獲取標(biāo)識strList.Add(pointWord + clist[j]);}else{strList.Add(clist[j]);}}}string reverseData = "M" + string.Join(" ", strList);return reverseData;}private void btnPositive_Click(object sender, RoutedEventArgs e){MatrixStory(0, this.path0.Data.ToString());}private void btnRevPositive_Click(object sender, RoutedEventArgs e){string data = this.path0.Data.ToString();var result = ConvertReverseData(data);MatrixStory(1, result);}/// <summary>/// /// </summary>/// <param name="orientation">0正向 1反向</param>/// <param name="data">路徑數(shù)據(jù)</param>private void MatrixStory(int orientation, string data){Border border = new Border();border.Width = 10;border.Height = 10;border.Visibility = Visibility.Collapsed;if (orientation==0){border.Background = new SolidColorBrush(Colors.Blue);}else{border.Background = new SolidColorBrush(Colors.Green);}this.canvas.Children.Add(border);Canvas.SetLeft(border, -border.Width / 2);Canvas.SetTop(border, -border.Height / 2);border.RenderTransformOrigin = new Point(0.5, 0.5);MatrixTransform matrix = new MatrixTransform();TransformGroup groups = new TransformGroup();groups.Children.Add(matrix);border.RenderTransform = groups;//NameScope.SetNameScope(this, new NameScope());string registname = "matrix" + Guid.NewGuid().ToString().Replace("-", "");this.RegisterName(registname, matrix);MatrixAnimationUsingPath matrixAnimation = new MatrixAnimationUsingPath();matrixAnimation.PathGeometry = PathGeometry.CreateFromGeometry(Geometry.Parse(data));matrixAnimation.Duration = new Duration(TimeSpan.FromSeconds(5));matrixAnimation.DoesRotateWithTangent = true;//旋轉(zhuǎn)//matrixAnimation.FillBehavior = FillBehavior.Stop;Storyboard story = new Storyboard();story.Children.Add(matrixAnimation);Storyboard.SetTargetName(matrixAnimation, registname);Storyboard.SetTargetProperty(matrixAnimation, new PropertyPath(MatrixTransform.MatrixProperty));#region 控制顯示與隱藏ObjectAnimationUsingKeyFrames ObjectAnimation = new ObjectAnimationUsingKeyFrames();ObjectAnimation.Duration = matrixAnimation.Duration;DiscreteObjectKeyFrame kf1 = new DiscreteObjectKeyFrame(Visibility.Visible, TimeSpan.FromMilliseconds(1));ObjectAnimation.KeyFrames.Add(kf1);story.Children.Add(ObjectAnimation);//Storyboard.SetTargetName(border, border.Name);Storyboard.SetTargetProperty(ObjectAnimation, new PropertyPath(UIElement.VisibilityProperty));#endregionstory.FillBehavior = FillBehavior.Stop;story.Begin(border, true);}} } View Code

執(zhí)行效果如下:

?

寫這個Path反轉(zhuǎn)的目的是動態(tài)生成動畫的時候,可以逆向執(zhí)行動畫,而不必為逆向動畫重新畫一個Path.

上面代碼中反轉(zhuǎn)Path有bug(各種不同的Path數(shù)據(jù)格式,下面是修復(fù)后的代碼)

?

string ConvertReverseData(string data){data = data.Replace("M", "");Regex regex = new Regex("[a-z]", RegexOptions.IgnoreCase);MatchCollection mc = regex.Matches(data);//item1 從上一個位置到當(dāng)前位置開始的字符 (match.Index=原始字符串中發(fā)現(xiàn)捕獲的子字符串的第一個字符的位置。)//item2 當(dāng)前發(fā)現(xiàn)的匹配符號(L C Z M)List<Tuple<string, string>> tmpList = new List<Tuple<string, string>>();int curPostion = 0;for (int i = 0; i < mc.Count; i++){Match match = mc[i];if (match.Index != curPostion){string str = data.Substring(curPostion, match.Index - curPostion);tmpList.Add(new Tuple<string, string>(str, match.Value));}curPostion = match.Index + match.Length;if (i + 1 == mc.Count)//last {tmpList.Add(new Tuple<string, string>(data.Substring(curPostion), match.Value));}}List<string[]> spList = new List<string[]>();Regex regexnum = new Regex(@"(\-?\d+\.?\d*)", RegexOptions.IgnoreCase);for (int i = 0; i < tmpList.Count; i++){//處理坐標(biāo)數(shù)據(jù) ex M 96 288 C 576 0, 0 0, 480 288//ex M 10,100 C 35,0 135,0 160,100 180,190 285,200 310,100//ex M95,50 L324.67997,50 324.67997,119.67997 234.67998,119.67997 234.67998,184.68002 //344.67999,184.68002 394.68,134.67999 C394.68,134.67999 394.68,189.68005//394.68,129.68002 394.68,69.679984 434.68002,89.679985 434.68002,89.679985// L477.18005,132.18003 477.18005,164.68004 419.68006,164.6800MatchCollection childMcs = regexnum.Matches(tmpList[i].Item1);if (childMcs.Count % 2 != 0){//分組數(shù)據(jù)有問題continue;}int groups = childMcs.Count / 2;var strTmp = new string[groups];for (int j = 0; j < groups; j++){string cdatas = childMcs[j * 2] + "," + childMcs[j * 2 + 1];//重組數(shù)據(jù)strTmp[j] = cdatas;}spList.Add(strTmp);}#region 逆向數(shù)據(jù)List<string> strList = new List<string>();for (int i = spList.Count - 1; i >= 0; i--){string[] clist = spList[i];for (int j = clist.Length - 1; j >= 0; j--){if (j == clist.Length - 2 && i > 0)//對于第二個元素增加 L或者C的標(biāo)識 {var pointWord = tmpList[i - 1].Item2;//獲取標(biāo)識strList.Add(pointWord + clist[j]);}else{strList.Add(clist[j]);//M10,50 L44.679973,69.679973 C43.627604,76.057983 43.410881,76.928271 41.082803,81.687898if (clist.Length == 1 && i > 0)//說明只有一個元素 ex L44.679973,69.679973 {strList.Add(tmpList[i - 1].Item2);}}}}string reverseData = "M" + string.Join(" ", strList);#endregionreturn reverseData;} View Code

?

如果大家在使用過程中還有發(fā)現(xiàn)算法bug,請在下方評論并把data貼出來。粘貼格式如下:

<Path x:Name="path0" Data="M 96 288 C 576 0, 0 0, 480 288" Stretch="None" Stroke="#FF61E70A" StrokeThickness="2" />

?

?源代碼下載

轉(zhuǎn)載于:https://www.cnblogs.com/ligl/p/5665306.html

總結(jié)

以上是生活随笔為你收集整理的WPF路径动画(动态逆向动画)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。