我制作动画。
使用ArcSegment绘制路径。
继续前进。
然而,不同于动画的起点和路径的起点。
应该修改什么?
此图片..开始动画后立即。
圆圈位置位于路径的中间。
我想帮助我。拜托......
动画部分。源代码
我创建了演示版。 我的源代码用韩文写的。所以创建演示版
如果您继续点击第二个按钮。
路径的起点和起点的不同起点。
如果有其他方法可能。
更改来源时并不重要。
这只是为了成功。我们期待取得好成绩。
你是一个非常好的人。谢谢
XAML
<Window x:Class="WpfApplication7.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="400" Width="830">
<Grid>
<Button x:Name="num_bt" Content="1.create number" HorizontalAlignment="Left" VerticalAlignment="Top" Width="118" Click="num_bt_Click"/>
<Button x:Name="start" Content="2.start animation" HorizontalAlignment="Left" Margin="-2,50,0,0" VerticalAlignment="Top" Width="118" Click="draw_bt_Click"/>
<Label Content="contiue click" HorizontalAlignment="Left" Margin="0,97,0,0" VerticalAlignment="Top" Width="116"/>
<Label Content="start animation btn" HorizontalAlignment="Left" Margin="0,120,0,0" VerticalAlignment="Top" Width="116"/>
<Canvas x:Name="canvas" HorizontalAlignment="Left" Height="373" Margin="137,0,0,0" VerticalAlignment="Top" Width="685"/>
</Grid>
背后的代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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 WpfApplication7
{
/// <summary>
/// MainWindow.xaml에 대한 상호 작용 논리
/// </summary>
public partial class MainWindow : Window
{
int num_count = 10; // use data number
List<int> sampleNumbers; // Save a number to use for sorting
int count = 1; // count
Ellipse[] Circle;
List<double> SaveCircleStartPoint;
struct SaveCircleProperty
{
public double Circle_stposX;
public double Circle_stposY;
public double radian;
}
List<SaveCircleProperty> SaveCircleInfos;
// save changed sorting info
struct SortingTraceInfo
{
public int Position; // change position
public int TargetPosition; // will change position
public int[] SortingNumbers; // sorting numbers
}
// save changed sorting info
List<SortingTraceInfo> sortingInfos;
int sortingInfosIndex;
public MainWindow()
{
InitializeComponent();
}
private void num_bt_Click(object sender, RoutedEventArgs e)
{
Random _random = new Random(); // create number
int[] num = new int[10];
sampleNumbers = new List<int>();
for (int i = 0; i < num_count; i++)
{
num[i] = _random.Next(1, 50);
sampleNumbers.Add(num[i]); // save number data
}
BubbleSort();
drawCircle(num_count, sampleNumbers);
}
private void draw_bt_Click(object sender, RoutedEventArgs e)
{
// draw a path and start animation
SortingTraceInfo traceInfo = this.sortingInfos[this.sortingInfosIndex++];
draw_path(traceInfo.Position, traceInfo.TargetPosition);
}
// draw circle
private void drawCircle(int num, List<int> size)
{
// saving a position to draw a circle
SaveCircleStartPoint = new List<double>();
SaveCircleInfos = new List<SaveCircleProperty>();
// To create the circle by the number of input num
Circle = new Ellipse[num];
int location = ((685 / num) - 5); // circle startpoint
int x = 50; // Width
int y = 115; // Height
for (int i = 0; i < num; i++)
{
double circlesize = size[i] + 10;
double radius = circlesize / 2; // radius
double st_posX = x - radius; // circular X-axis position
double st_posY = y - radius; // circular Y-axis position
SaveCircleProperty cp = new SaveCircleProperty();
// define circle property
Circle[i] = new Ellipse();
Circle[i].Name = "circle" + i.ToString();
Circle[i].Stroke = Brushes.Red;
Circle[i].StrokeThickness = 5;
Circle[i].Width = circlesize;
Circle[i].Height = circlesize;
// position of canvs
Canvas.SetLeft(Circle[i], st_posX); // startpoint x-axis
Canvas.SetTop(Circle[i], st_posY); // startpoint Y-axis
// save circls's property
SaveCircleStartPoint.Add(st_posX);
cp.Circle_stposX = st_posX;
cp.Circle_stposY = st_posY;
cp.radian = radius;
SaveCircleInfos.Add(cp);
// startpoint
x += location;
// add canvas
canvas.Children.Add(Circle[i]);
this.RegisterName(Circle[i].Name, Circle[i]);
}
}
private void draw_path(int pos1, int pos2)
{
SaveCircleProperty scp = this.SaveCircleInfos[pos1];
SaveCircleProperty scp2 = this.SaveCircleInfos[pos2];
create_path(scp.Circle_stposX, scp.Circle_stposY, scp2.Circle_stposX, scp2.Circle_stposY, scp.radian, scp2.radian, pos1, pos2);
}
private void create_path(double startPoint, double startPoint2, double endPoint, double endPoint2, double radian1, double radian2, int position, int tartgetPosition)
{
// regist name
NameScope.SetNameScope(this, new NameScope());
NameScope.SetNameScope(canvas, new NameScope());
// circls position reset
Canvas.SetLeft(Circle[position], 0);
Canvas.SetTop(Circle[position], 0);
Canvas.SetLeft(Circle[tartgetPosition], 0);
Canvas.SetTop(Circle[tartgetPosition], 0);
///<summary>
/// Circle left the road going from left to right
///</summary>
PathGeometry pathGeometryLeft = new PathGeometry();
PathFigure Leftfigure = new PathFigure();
Leftfigure.StartPoint = new Point(startPoint, startPoint2); // x-axis , y-axis start point
// point(x-axis, y-axis)
Leftfigure.Segments.Add(new ArcSegment(new Point(endPoint, startPoint2), new Size(150, endPoint - startPoint), 90, false, SweepDirection.Clockwise, true));
pathGeometryLeft.Figures.Add(Leftfigure);
Path Leftpath = new Path();
Leftpath.Data = pathGeometryLeft;
Leftpath.Stroke = Brushes.Green;
canvas.Children.Add(Leftpath);
MatrixTransform LeftcircleMatrixTransform = new MatrixTransform();
Circle[position].RenderTransform = LeftcircleMatrixTransform;
this.RegisterName("LeftCircleMatrixTransform" + count.ToString(), LeftcircleMatrixTransform);
pathGeometryLeft.Freeze();
// Create a MatrixAnimationUsingPath to move the
// circle along the path by animating
// its MatrixTransform.
MatrixAnimationUsingPath Leftmatrixanimation = new MatrixAnimationUsingPath();
Leftmatrixanimation.PathGeometry = pathGeometryLeft;
Leftmatrixanimation.Duration = TimeSpan.FromSeconds(5);
Leftmatrixanimation.DoesRotateWithTangent = true;
// Set the animation to target the Matrix property
// of the MatrixTransform named "ButtonMatrixTransform".
Storyboard.SetTargetName(Leftmatrixanimation, "LeftCircleMatrixTransform" + count.ToString());
Storyboard.SetTargetProperty(Leftmatrixanimation, new PropertyPath(MatrixTransform.MatrixProperty));
// Create a Storyboard to contain and apply the animation.
Storyboard LeftpathAnimationStoryboard = new Storyboard();
LeftpathAnimationStoryboard.Children.Add(Leftmatrixanimation);
LeftpathAnimationStoryboard.Begin(this);
/// <summary>
/// The road to the right circle from right to left (path)
/// </summary>
PathGeometry RightpathGeometry = new PathGeometry();
PathFigure Rightfigure = new PathFigure();
Rightfigure.StartPoint = new Point(endPoint, endPoint2 + (radian2 * 2)); // x축 , y축 시작점
// point(x축 끝, y축 끝점)
Rightfigure.Segments.Add(new ArcSegment(new Point(startPoint, endPoint2 + (radian2 * 2)), new Size(150, endPoint - startPoint), 90, false, SweepDirection.Clockwise, true));
// this.RegisterName("RightmyArcSegment", Rightfigure.Segments);
RightpathGeometry.Figures.Add(Rightfigure);
Path Rightpath = new Path();
Rightpath.Data = RightpathGeometry;
Rightpath.Stroke = Brushes.Red;
canvas.Children.Add(Rightpath);
MatrixTransform RightcircleMatrixTransform = new MatrixTransform();
Circle[tartgetPosition].RenderTransform = RightcircleMatrixTransform;
this.RegisterName("RightCircleMatrixTransform" + count.ToString(), RightcircleMatrixTransform);
RightpathGeometry.Freeze();
MatrixAnimationUsingPath Rightmatrixanimation = new MatrixAnimationUsingPath();
Rightmatrixanimation.PathGeometry = RightpathGeometry;
Rightmatrixanimation.Duration = TimeSpan.FromSeconds(10);
// Set the animation's DoesRotateWithTangent property
// to true so that rotates the rectangle in addition
// to moving it.
Rightmatrixanimation.DoesRotateWithTangent = true;
// Set the animation to target the Matrix property
// of the MatrixTransform named "CircleMatrixTransform".
Storyboard.SetTargetName(Rightmatrixanimation, "RightCircleMatrixTransform" + count.ToString());
Storyboard.SetTargetProperty(Rightmatrixanimation, new PropertyPath(MatrixTransform.MatrixProperty));
// Create a Storyboard to contain and apply the animation.
Storyboard RightpathAnimationStoryboard = new Storyboard();
RightpathAnimationStoryboard.Children.Add(Rightmatrixanimation);
RightpathAnimationStoryboard.Begin(this);
Ellipse temp = null;
temp = Circle[position];
Circle[position] = Circle[tartgetPosition];
Circle[tartgetPosition] = temp;
count++;
}
// 버블 정렬
private List<int> BubbleSort()
{
sortingInfos = new List<SortingTraceInfo>();
List<int> sorting = new List<int>(sampleNumbers);
for (int i = 0; i < sorting.Count - 1; i++)
{
for (int j = 0; j < sorting.Count - 1 - i; j++)
{
if (sorting[j] > sorting[j + 1])
{
Swap(sorting, j, j + 1);
SortingTraceInfo sortInfo = new SortingTraceInfo(); //
sortInfo.Position = j; // save change position
sortInfo.TargetPosition = j + 1; // save will change position
sortInfo.SortingNumbers = sorting.ToArray(); // sorting number saved to array
sortingInfos.Add(sortInfo); // 변경 정보등을 sortingInfos 리스트에 저장
}
}
}
return sorting;
}
private void Swap(List<int> num, int i, int j)
{
int temp = num[i];
num[i] = num[j];
num[j] = temp;
}
}
}
答案 0 :(得分:1)
private void draw_path(int pos1, int pos2)
{
var circles = canvas.Children.OfType<Ellipse>().OrderBy(q => (double)q.GetValue(Canvas.LeftProperty)).ToList();
var circle1 = circles[pos1];
var circle2 = circles[pos2];
// horizontal animation for circle1
Storyboard sb1 = new Storyboard();
double from1 = (double)circle1.GetValue(Canvas.LeftProperty);
double to1 = (double)circle2.GetValue(Canvas.LeftProperty) + circle2.ActualWidth / 2 - circle1.ActualWidth / 2;
DoubleAnimation da1 = new DoubleAnimation(from1, to1, new Duration(TimeSpan.FromSeconds(0.6)));
Storyboard.SetTarget(sb1, circle1);
Storyboard.SetTargetProperty(sb1, new PropertyPath(Canvas.LeftProperty));
sb1.Children.Add(da1);
// horizontal animation for circle2
Storyboard sb2 = new Storyboard();
double from2 = (double)circle2.GetValue(Canvas.LeftProperty);
double to2 = (double)circle1.GetValue(Canvas.LeftProperty) + circle1.ActualWidth / 2 - circle2.ActualWidth / 2;
DoubleAnimation da2 = new DoubleAnimation(from2, to2, new Duration(TimeSpan.FromSeconds(0.6)));
Storyboard.SetTarget(sb2, circle2);
Storyboard.SetTargetProperty(sb2, new PropertyPath(Canvas.LeftProperty));
sb2.Children.Add(da2);
// vertical animation for circle1
Storyboard sb3 = new Storyboard();
double from3 = (double)circle1.GetValue(Canvas.TopProperty);
double to3 = (double)circle1.GetValue(Canvas.TopProperty) + circle1.ActualWidth;
DoubleAnimation da3 = new DoubleAnimation(from3, to3, new Duration(TimeSpan.FromSeconds(0.3)));
da3.AutoReverse = true;
da3.AccelerationRatio = 0.1;
Storyboard.SetTarget(sb3, circle1);
Storyboard.SetTargetProperty(sb3, new PropertyPath(Canvas.TopProperty));
sb3.Children.Add(da3);
// vertical animation for circle2
Storyboard sb4 = new Storyboard();
double from4 = (double)circle2.GetValue(Canvas.TopProperty);
double to4 = (double)circle2.GetValue(Canvas.TopProperty) - circle2.ActualWidth;
DoubleAnimation da4 = new DoubleAnimation(from4, to4, new Duration(TimeSpan.FromSeconds(0.3)));
da4.AutoReverse = true;
da4.AccelerationRatio = 0.1;
Storyboard.SetTarget(sb4, circle2);
Storyboard.SetTargetProperty(sb4, new PropertyPath(Canvas.TopProperty));
sb4.Children.Add(da4);
sb1.Begin();
sb2.Begin();
sb3.Begin();
sb4.Begin();
}
希望,这有帮助