WPF实现Loading加载文字水波纹动画效果

实现效果如下:

WPF实现Loading加载文字水波纹动画效果_第1张图片

思路:基本原理同博文WPF实现聚光灯动画效果一致,难点在与正弦曲线的绘制和动态效果。

步骤:

1、自定义控件MyLoadingControl的封装

添加自定义Value属性:

        public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(int), typeof(MyLoadingControl), new PropertyMetadata(null));
        public int Value
        {
            get { return (int)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }

xaml布局:

    
        
        
        
    

生成正弦曲线方法:

        /// 
        /// 得到正弦曲线
        /// 
        /// 水纹宽度
        /// 水纹振幅
        /// 水纹周期
        /// 位移
        /// 当前波浪高度
        /// 
        public StreamGeometry GetSinGeometry(double waveWidth, double waveA, double waveW, double offsetX, double currentK)
        {
            StreamGeometry g = new StreamGeometry();
            using (StreamGeometryContext ctx = g.Open())
            {
                ctx.BeginFigure(new Point(0, 0), true, true);
                for (int x = 0; x < waveWidth; x += 1)
                {
                    double y = waveA * Math.Sin(x * waveW + offsetX) + currentK;
                    ctx.LineTo(new Point(x, y), true, true);
                }
                ctx.LineTo(new Point(waveWidth, 0), true, true);
            }
            return g;
        }

添加DispatcherTimer计时器驱动:

        private DispatcherTimer frameTimer;
        private StreamGeometry myPathGeometry;

        public MyLoadingControl()
        {
            InitializeComponent();

            CompositionTarget.Rendering += UpdateRectangle;

            frameTimer = new DispatcherTimer();
            frameTimer.Tick += OnFrame;
            frameTimer.Interval = TimeSpan.FromSeconds(3.0 / 60.0);
            frameTimer.Start();
        }

        private void OnFrame(object sender, EventArgs e)
        {
            this.GeometryCanvas.Children.Clear();
            if (Value > 100)
            {
                if(frameTimer != null)
                    frameTimer.Stop();
            }
            Value++;
            myPathGeometry = GetSinGeometry(this.Width, -5, 1 / 30.0, -this.Width + this.Width * Value / 100, this.Height - this.Height * Value / 100);
            GeometryGroup group = new GeometryGroup();
            group.Children.Add(myPathGeometry);

            Path myPath = new Path();
            myPath.Fill = Brushes.Transparent;
            myPath.Data = group;

            this.GeometryCanvas.Children.Add(myPath);
        }

        private void UpdateRectangle(object sender, EventArgs e)
        {
            this.GeometryText.Clip = myPathGeometry;
        }

2、主窗体调用

    
        
    

 

你可能感兴趣的:(WPF应用实例)