创建可动画的2D wpf自定义形状

时间:2012-06-22 23:36:27

标签: c# wpf animation 2d

目前我正在开发一个项目,该项目涉及在WPF中设置自定义构建的2D形状。形状看起来像一个盒子,目前我似乎有一些小问题。

这是我的代码目前的样子

namespace Wpftrial4
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        SolidColorBrush fillcolor = new SolidColorBrush();
        SolidColorBrush bordercolor = new SolidColorBrush();


        public MainWindow()
        {
            InitializeComponent();

            fillcolor.Color = Colors.WhiteSmoke;
            bordercolor.Color = Colors.Blue;


        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {

            //Manually creating the required 2D Box shape
            Path path_rectangle = new Path();

            path_rectangle.Fill = fillcolor;
            path_rectangle.Stroke = bordercolor;
            path_rectangle.StrokeThickness = 5;

            RectangleGeometry rg = new RectangleGeometry();
            double width_rec = 100; 
            double height_rec = 50;
            double left_rec = 130; 
            double top_rec = 100;
            rg.Rect = new Rect(left_rec, top_rec, width_rec, height_rec);
            path_rectangle.Data = rg;
            canvas1.Children.Add(path_rectangle);


            Path path2_top = new Path();
            path2_top.Stroke = new SolidColorBrush(Colors.Brown);
            path2_top.StrokeThickness = 6;
            RectangleGeometry rg2 = new RectangleGeometry();
            double width2 = 100;
            double height2 = 2;
            double left2 = 130;
            double top2 = 90;
            rg2.Rect = new Rect(left2, top2, width2, height2);
            path2_top.Data = rg2;
            canvas1.Children.Add(path2_top);


            Path path3_topcover = new Path();
            path3_topcover.Stroke = new SolidColorBrush(Colors.White);
            path3_topcover.StrokeThickness = 5;
            RectangleGeometry rg3 = new RectangleGeometry();
            double width3 = 100;
            double height3 = 5;
            double left3 = 130;
            double top3 = 100;
            rg3.Rect = new Rect(left3, top3, width3, height3);
            path3_topcover.Data = rg3;
            canvas1.Children.Add(path3_topcover);


            //combining part_Group type
            GeometryGroup myGeometryGroup = new GeometryGroup();
            myGeometryGroup.Children.Add(rg);
            myGeometryGroup.Children.Add(rg3);
            Path myPath = new Path();
            myPath.Stroke = Brushes.Blue;
            myPath.Data = myGeometryGroup;
            canvas1.Children.Add(myPath);





            ////test animate
            //myCustomAnimatedBox MB2 = new myCustomAnimatedBox(200, 200, 300, 250) { Stroke = Brushes.Black, StrokeThickness = 2 };
            //canvas1.Children.Add(MB2); //new myCustomAnimatedBox(200, 200, 300, 250,500,500){Stroke = Brushes.Black, StrokeThickness = 2});
            //PointAnimation pa2 = new PointAnimation();
            ////DoubleAnimation da = new DoubleAnimation();
            //pa2.To = new Point(100, 100);
            ////da.By = 50;
            //pa2.Duration = TimeSpan.FromSeconds(10);
            ////MB2.BeginAnimation(myCustomAnimatedBox.TopProperty,pa2);//(//MB2.BeginAnimation(myCustomAnimatedBox.CenterProperty, pa2);

        }

        //class- style custom2D shape creation
        private void button2_Click(object sender, RoutedEventArgs e)
        {
            myCustomAnimatedBox MB = new myCustomAnimatedBox(200, 200, 350, 250) { Stroke = Brushes.Black, StrokeThickness = 2 };
            canvas1.Children.Add(MB); //new myCustomAnimatedBox(200, 200, 300, 250,500,500){Stroke = Brushes.Black, StrokeThickness = 2});
            //PointAnimation pa = new PointAnimation();
            ////DoubleAnimation da = new DoubleAnimation();
            //pa.To = new Point(100, 100);
            ////da.By = 50;
            //pa.Duration = TimeSpan.FromSeconds(10);
            //MB.BeginAnimation(myCustomAnimatedBox.CenterProperty, pa);



        }
    }

    //Class that defines the custom 2D shape
    public class myCustomAnimatedBox : Shape
    {
        private double x1, width;
        private double y1, height;

        private GeometryGroup myBox = new GeometryGroup();


        public myCustomAnimatedBox(double XX1, double YY1, double widTH, double heiGHT)
        {  
            makeBox(XX1, YY1, widTH, heiGHT);

        }



        //public static readonly DependencyProperty CenterProperty = DependencyProperty.Register("Center", typeof(Point), typeof(myCustomAnimatedBox),
        //    new PropertyMetadata( null,PropertyChanged));// FrameworkPropertyMetadata( FrameworkPropertyMetadataOptions.AffectsMeasure));
        ////new Point(cent_X, cent_Y)

        //public Point Center
        //{
        //    get { return (Point)GetValue(CenterProperty); }
        //    set 
        //    { 

        //        SetValue(CenterProperty, value);
        //        myBox.Children.Clear();
        //        makeBox(myBox, value.X, value.Y, width, height);
        //    }
        //}

        //public Point Center
        //{
        //    get { return (Point)GetValue(CenterProperty); }
        //    set
        //    {

        //        SetValue(CenterProperty, value);
        //        myBox.Children.Clear();
        //        makeBox(myBox, value.X, value.Y, width, height);
        //    }
        //}
        //public Point Top
        //{
        //    get { return new Point(X1, Y1); }
        //    set 
        //    { 
        //        //X1 = value.X;
        //        //Y1 = value.Y;
        //        Top = value;

        //    }

        //}

        //public static readonly DependencyProperty TopProperty = DependencyProperty.Register("Top", typeof(Point), typeof(myCustomAnimatedBox), new FrameworkPropertyMetadata( FrameworkPropertyMetadataOptions.AffectsMeasure));
            //new PropertyMetadata( null,PropertyChanged));

        public double X1
        {
            get { return x1; }
            set 
            {
                x1 = value;

            }
        }

        public double Y1
        {
            get { return y1; }
            set 
            {
                y1 = value;

            }
        }


        //Trial at creating a dependency property
        //private static void TopPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        //{
        //    myCustomAnimatedBox myB = (myCustomAnimatedBox)d;


        //    myB.InvalidateVisual();



        //}

        protected override Geometry DefiningGeometry
        {
            get { return myBox; }
        }

        //Function that draws the object
        private void makeBox(double XX1, double YY1, double widTH, double heiGHT)
        {

            width = widTH;
            height = heiGHT;
            this.X1 = XX1;
            this.Y1 = YY1;
            RectangleGeometry rectangle_part = new RectangleGeometry();
            rectangle_part.Rect = new Rect(X1,Y1,width,height);
            RectangleGeometry rg_cover = new RectangleGeometry();
            RectangleGeometry rg_top = new RectangleGeometry();
            rg_top.Rect = new Rect(X1, Y1 - 10, width, 2);
            rg_cover.Rect = new Rect(X1, Y1, width, 5);
            myBox.Children.Add(rectangle_part);
            myBox.Children.Add(rg_top);
            myBox.Children.Add(rg_cover);


        }


    }
}

由于形状将经历动画,例如:盒子打开和关闭,我需要自定义形状以具有可移动部分。根据大多数作者的GeometryGroup似乎在动画加上其他数据绑定时提供了最大的优势。在我测试的代码中手动创建形状。这可以在附加到Button1的代码中看到。然而,当我尝试进行类实现时,我无法获得我想要的那种效果,例如改变单个组成特征。我在WPF学习不到1个月,希望在以下方面提供帮助。

  1. GeometryGroup是否适合我想要实现的目标?
  2. 将遵循此课程,以实现我的目标。即我能够为WPF内置的自定义2D形状的一部分制作动画,即盒子 - 打开;盒---关闭。
  3. 有人可以告诉我我需要做些什么才能改变组成形状的个别属性,即我自定义形状的矩形。
  4. 感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

制作动画2d形状的最佳选择是使用表达式混合软件:Download link software 你可以在这里看到一个示例教程:Introduction to Blend: Animation