zoukankan      html  css  js  c++  java
  • WPF 简易的喷泉效果

    这两天领导让我做个喷泉的效果,要把一个个UserControl从一个位置喷出,然后,最后落在最终需要在的位置。

    喷泉效果说白了,就是两个步骤:1、放大,从0放大到需要的倍数;2、缩小,平移,从放大的倍数还原到UserControl的原始大小,并且定位到最终的位置。

    虽然,只有两步,但是,作为写动画的新手,还是有点费事的,所以,采用了先用Blend设计,然后再转换为C#代码的过程。

    一、Blend设计单个UserControl的放大和移动效果

    1、在Blend里,新建个项目,然后,在Grid下,放个Canvas,在Canvas下放个Image(先拿Image来设计)

    2、在Blend左侧的时间线,选中image控件,然后点击上面的+号,会弹出新增动画资源的弹窗,点击确定。

    3、根据需要,拖拽左侧的时间线(黄线)到对应位置,然后,对红框中的Image控件,进行放大、缩小、位置调整等操作。

    4、XAML部分,产生了相应的代码

    <Window.Resources>
            <Storyboard x:Key="StoryboardFountain">
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" Storyboard.TargetName="image">
                    <EasingDoubleKeyFrame KeyTime="0:0:0" Value="0"/>
                    <EasingDoubleKeyFrame KeyTime="0:0:5" Value="5"/>
                    <EasingDoubleKeyFrame KeyTime="0:0:10" Value="1"/>
                </DoubleAnimationUsingKeyFrames>
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" Storyboard.TargetName="image">
                    <EasingDoubleKeyFrame KeyTime="0:0:0" Value="0"/>
                    <EasingDoubleKeyFrame KeyTime="0:0:5" Value="5"/>
                    <EasingDoubleKeyFrame KeyTime="0:0:10" Value="1"/>
                </DoubleAnimationUsingKeyFrames>
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="image">
                    <EasingDoubleKeyFrame KeyTime="0:0:5" Value="0"/>
                    <EasingDoubleKeyFrame KeyTime="0:0:10" Value="-186.5"/>
                </DoubleAnimationUsingKeyFrames>
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" Storyboard.TargetName="image">
                    <EasingDoubleKeyFrame KeyTime="0:0:5" Value="0"/>
                    <EasingDoubleKeyFrame KeyTime="0:0:10" Value="-107"/>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>
            <Storyboard x:Key="Storyboard1"/>
        </Window.Resources>
        <Window.Triggers>
            <EventTrigger RoutedEvent="FrameworkElement.Loaded">
                <BeginStoryboard Storyboard="{StaticResource StoryboardFountain}"/>
            </EventTrigger>
        </Window.Triggers>
        <Grid>
            <Canvas HorizontalAlignment="Center" VerticalAlignment="Center">
                <Image x:Name="image" Source="C:UsersdellPicturesWP_20160112_18_55_33_Raw_LI.jpg" Width="50" Height="50" Canvas.Left="-0.5" Canvas.Top="-0.5" RenderTransformOrigin="0.5,0.5">
                    <Image.RenderTransform>
                        <TransformGroup>
                            <ScaleTransform/>
                            <SkewTransform/>
                            <RotateTransform/>
                            <TranslateTransform/>
                        </TransformGroup>
                    </Image.RenderTransform>
                </Image>
            </Canvas>
        </Grid>

     

    二、把XAML代码转换为C#

    有了XAML代码,转换成C#代码,就方便多了,只要把对应的部分相关转换,然后启动动画,就OK了

    TransformGroup部分转换为如下的方式

    if (uc.RenderTransform as TransformGroup == null)
    {
        TransformGroup tg = new TransformGroup();
        uc.RenderTransform = tg;
        tg.Children.Add(new ScaleTransform());
        tg.Children.Add(new TranslateTransform());
    }

    由于,实际上只用到了ScaleTransform和TranslateTransform,所以,就只写了两个

     DoubleAnimationUsingKeyFrames部分转换为如下的方式

    EasingDoubleKeyFrame edf1 = new EasingDoubleKeyFrame(Init, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(i + first_value)));
    EasingDoubleKeyFrame edf2 = new EasingDoubleKeyFrame(Mul, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(i + middle_value)));
    EasingDoubleKeyFrame edf3 = new EasingDoubleKeyFrame(Org, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(i + end_value)));
    
    DoubleAnimationUsingKeyFrames daukf1 = new DoubleAnimationUsingKeyFrames();
    daukf1.KeyFrames.Add(edf1);
    daukf1.KeyFrames.Add(edf2);
    daukf1.KeyFrames.Add(edf3);
    storyboard.Children.Add(daukf1);
    Storyboard.SetTarget(daukf1, uc);
    Storyboard.SetTargetProperty(daukf1, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"));

     对比过XAML代码和C#代码以后,就发现,其实XAML转C#,还是没有那么困难的,就是把相应的位置进行相关的添加值,可以直接从XAML里复制过来,如(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX),谁能记得住呢,反正我记不住,太笨了。

    写好了一个UserControl的效果以后,多个的实现起来,就容易了,无外乎就是for循环,设置参数而已。

    定义一个UCShow的类,里面包含了UC和最后要定位的位置,如下,将需要展示的集合,都添加到一个List里就ok了。

    public class UcShow
    {
        private UIElement uc;
        private double top;
        private double left;
    
        public UIElement Uc
        {
            get
            {
                return uc;
            }
    
            set
            {
                uc = value;
            }
        }
    
        public double Top
        {
            get
            {
                return top;
            }
    
            set
            {
                top = value;
            }
        }
    
        public double Left
        {
            get
            {
                return left;
            }
    
            set
            {
                left = value;
            }
        }
    }

    效果如下:

    喷泉效果的代码如下:

    class Fountain
    {
        /// <summary>
        /// 喷泉效果
        /// </summary>
        /// <param name="cav">画布</param>
        /// <param name="uclist">展示集合</param>
        /// <param name="pL">喷出点左</param>
        /// <param name="pT">喷出点上</param>
        /// <param name="Mul">放大倍数</param>
        /// <param name="middle_value">放大时间点</param>
        /// <param name="end_value">还原时间点</param>
        public void FountainAnimation(Canvas cav,List<UcShow> uclist, double pL = 0, double pT = 0, double Mul = 10, double middle_value = 0.5, double end_value = 1)
        {
            if (uclist.Count <= 0)
            {
                return;
            }
            Storyboard storyboard = new Storyboard();
    
            double Init = 0;
            double Org = 1;
            double first_value = 0;
    
            for (int i = 0; i < uclist.Count; i++)
            {
                UIElement uc = uclist[i].Uc;
                double Top = uclist[i].Top;
                double Left = uclist[i].Left;
                Canvas.SetLeft(uc, pL);
                Canvas.SetTop(uc, pT);
                if (uc.RenderTransform as TransformGroup == null)
                {
                    uc.RenderTransformOrigin = new Point(0.5, 0.5);
                    TransformGroup tg = new TransformGroup();
                    uc.RenderTransform = tg;
                    tg.Children.Add(new ScaleTransform());
                    tg.Children.Add(new TranslateTransform());
                }
                double first = i * 0.05 + first_value;
                double middle = i * 0.05 + middle_value;
                double end = i * 0.05 + end_value;
                EasingDoubleKeyFrame edf0 = new EasingDoubleKeyFrame(0, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0)));//所有元素起点都是0
                EasingDoubleKeyFrame edf1 = new EasingDoubleKeyFrame(Init, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(first)));
                EasingDoubleKeyFrame edf2 = new EasingDoubleKeyFrame(Mul, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(middle)));
                EasingDoubleKeyFrame edf3 = new EasingDoubleKeyFrame(Org, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(end)));
    
                DoubleAnimationUsingKeyFrames daukf1 = new DoubleAnimationUsingKeyFrames();
                daukf1.KeyFrames.Add(edf0);
                daukf1.KeyFrames.Add(edf1);
                daukf1.KeyFrames.Add(edf2);
                daukf1.KeyFrames.Add(edf3);
                storyboard.Children.Add(daukf1);
                Storyboard.SetTarget(daukf1, uc);
                Storyboard.SetTargetProperty(daukf1, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"));
    
                DoubleAnimationUsingKeyFrames daukf2 = new DoubleAnimationUsingKeyFrames();
                daukf2.KeyFrames.Add(edf0);
                daukf2.KeyFrames.Add(edf1);
                daukf2.KeyFrames.Add(edf2);
                daukf2.KeyFrames.Add(edf3);
                storyboard.Children.Add(daukf2);
                Storyboard.SetTarget(daukf2, uc);
                Storyboard.SetTargetProperty(daukf2, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"));
    
                DoubleAnimationUsingKeyFrames daukf3 = new DoubleAnimationUsingKeyFrames();
                EasingDoubleKeyFrame edf31 = new EasingDoubleKeyFrame(0, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(middle)));
                EasingDoubleKeyFrame edf32 = new EasingDoubleKeyFrame(Top, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(end)));
                daukf3.KeyFrames.Add(edf31);
                daukf3.KeyFrames.Add(edf32);
                storyboard.Children.Add(daukf3);
                Storyboard.SetTarget(daukf3, uc);
                Storyboard.SetTargetProperty(daukf3, new PropertyPath("(Canvas.Top)"));
    
                DoubleAnimationUsingKeyFrames daukf4 = new DoubleAnimationUsingKeyFrames();
                EasingDoubleKeyFrame edf41 = new EasingDoubleKeyFrame(0, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(middle)));
                EasingDoubleKeyFrame edf42 = new EasingDoubleKeyFrame(Left, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(end)));
                daukf4.KeyFrames.Add(edf41);
                daukf4.KeyFrames.Add(edf42);
                storyboard.Children.Add(daukf4);
                Storyboard.SetTarget(daukf4, uc);
                Storyboard.SetTargetProperty(daukf4, new PropertyPath("(Canvas.Left)"));
           cav.Children.Add(uc); } storyboard.FillBehavior
    = FillBehavior.HoldEnd; storyboard.Begin(); } }
  • 相关阅读:
    python---装饰器用法小结
    python---mysql事务
    python---sql语句集体更改数据
    python多继承中的深度优先与广度优先
    python---copy
    vue 主次页面区分
    css 过渡动画
    android web外壳
    cordova 打包 守护进程无法启动
    JavaScript 原生控制元素添加删除
  • 原文地址:https://www.cnblogs.com/ZXdeveloper/p/7837682.html
Copyright © 2011-2022 走看看