• Windows Phone中悬浮小助手的制作过程


    前言

         看到过其他平台游戏中第三方sdk的一些悬浮的小助手,近来无聊,就做个玩儿,看着比较简单,做起来还是花费了不少力气。

    开始

      首先是页面的xaml代码,其实比较简单,就是一些Canvas里面装了些image和一个border(是作为按钮展开后的背景)。下面注释的那个canvas是为了看到悬浮窗在界面右边的时的效果,方便做动画添加的,读者不用在意

      要求悬浮按钮可以拖动,拖动后靠在自动屏幕边上显示,拖动的时候超过屏幕的中轴就靠在右边,点击按钮向左边以此展开按钮,如果拖动后在屏幕中轴左边则靠左侧边上,点击屏幕向右依次展开,再次点击收回按钮。(展开按钮的时候我有添加了个选择动画,旋转了360度,)考虑到动画需要变化,以前悬浮窗的中的按钮位置也要根据拖放的位置动态变化,所以动画和布局都用代码控制。

     <phone:PhoneApplicationPage.Resources>
            <Style x:Key="imageS" TargetType="Image">
                <Setter Property="Width"  Value="50"/>
                <Setter Property="Height" Value="50"/>
                <Setter Property="RenderTransformOrigin" Value="0.5,0.5"/>
            </Style>
            <!--<Storyboard x:Name="Storyboard1">
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" Storyboard.TargetName="border">
                    <EasingDoubleKeyFrame KeyTime="0" Value="0.04"/>
                    <EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="1.003"/>
                </DoubleAnimationUsingKeyFrames>
           
                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="border">
                    <DiscreteObjectKeyFrame KeyTime="0">
                        <DiscreteObjectKeyFrame.Value>
                            <Visibility>Visible</Visibility>
                        </DiscreteObjectKeyFrame.Value>
                    </DiscreteObjectKeyFrame>
                    <DiscreteObjectKeyFrame KeyTime="0:0:0.4">
                        <DiscreteObjectKeyFrame.Value>
                            <Visibility>Visible</Visibility>
                        </DiscreteObjectKeyFrame.Value>
                    </DiscreteObjectKeyFrame>
                </ObjectAnimationUsingKeyFrames>
            </Storyboard>-->
        </phone:PhoneApplicationPage.Resources>
    
    <!--LayoutRoot 是包含所有页面内容的根网格-->
        <Grid>
            <Grid.Background>
                <ImageBrush Stretch="Fill" ImageSource="/Assets/Image/bg1.jpg"/>
            </Grid.Background>
    
            <Canvas x:Name="HoverContentner" HorizontalAlignment="Left" Height="50" Margin="0,0,0,0" VerticalAlignment="Top"  Width="300" >
                <Border Visibility="Collapsed" x:Name="border" Width="300" Height="47" HorizontalAlignment="Left" VerticalAlignment="Top" CornerRadius="12" Background="#B2D1DAC7" RenderTransformOrigin="0.0,0.0">
                    <Border.RenderTransform>
                        <CompositeTransform/>
                    </Border.RenderTransform>
                </Border>
                <Image x:Name="image0" Style="{StaticResource imageS}"  Source="/Assets/Image/button1.png" Tap="image0_Tap" ManipulationDelta="image0_ManipulationDelta" ManipulationCompleted="image0_ManipulationCompleted" >
                    <Image.RenderTransform>
                        <CompositeTransform/>
                    </Image.RenderTransform>
                </Image>
                <Image Visibility="Collapsed" x:Name="image1" Style="{StaticResource imageS}" Canvas.Left="60" Source="/Assets/Image/button2.png" >
                    <Image.RenderTransform>
                        <CompositeTransform/>
                    </Image.RenderTransform>
                </Image>
                <Image Visibility="Collapsed" x:Name="image2" Style="{StaticResource imageS}" Canvas.Left="120" Source="/Assets/Image/button3.png">
                    <Image.RenderTransform>
                        <CompositeTransform/>
                    </Image.RenderTransform>
                </Image>
                <Image Visibility="Collapsed" x:Name="image3" Style="{StaticResource imageS}"  Canvas.Left="180" Source="/Assets/Image/button4.png">
                    <Image.RenderTransform>
                        <CompositeTransform/>
                    </Image.RenderTransform>
                </Image>
                <Image Visibility="Collapsed" x:Name="image4" Style="{StaticResource imageS}" Canvas.Left="240" Source="/Assets/Image/button5.png" >
                    <Image.RenderTransform>
                        <CompositeTransform/>
                    </Image.RenderTransform>
                </Image>
            </Canvas>
    
    
            <!--<Canvas x:Name="HoverContentnerRight" HorizontalAlignment="Left" Height="50" Margin="180,300,0,0" VerticalAlignment="Top"  Width="300">           
                <Image Visibility="Visible"  Style="{StaticResource imageS}" Canvas.Left="180" Source="/Assets/Image/button2.png" >
                    <Image.RenderTransform>
                        <CompositeTransform/>
                    </Image.RenderTransform>
                </Image>
                <Image Visibility="Visible"  Style="{StaticResource imageS}"  Canvas.Left="120" Source="/Assets/Image/button3.png" >
                    <Image.RenderTransform>
                        <CompositeTransform/>
                    </Image.RenderTransform>
                </Image>
                <Image Visibility="Visible"   Style="{StaticResource imageS}" Canvas.Left="60" Source="/Assets/Image/button4.png" >
                    <Image.RenderTransform>
                        <CompositeTransform/>
                    </Image.RenderTransform>
                </Image>
                <Image Visibility="Visible"  Style="{StaticResource imageS}" Canvas.Left="0" Source="/Assets/Image/button5.png"  >
                    <Image.RenderTransform>
                        <CompositeTransform/>
                    </Image.RenderTransform>
                </Image>
                <Image x:Name="image0left" Style="{StaticResource imageS}"  Canvas.Left="240" Source="/Assets/Image/button1.png" Tap="image0_Tap" ManipulationDelta="image0_ManipulationDelta" ManipulationCompleted="image0_ManipulationCompleted" >
                    <Image.RenderTransform>
                        <CompositeTransform/>
                    </Image.RenderTransform>
                </Image>
            </Canvas>-->
        </Grid>
    
    </phone:PhoneApplicationPage>

      一些定义的变量

            private int trasnlateLength = 60;
            private bool left = true;
            private bool lastleft = true;//lastleft上次
            private Storyboard expandstory = null;
            private Storyboard hidestory = null;
            private bool isStoryBegin = true;

      首先是处理拖动的代码

        private void image0_ManipulationDelta(object sender, System.Windows.Input.ManipulationDeltaEventArgs e)
            {
                if (image1.Visibility == Visibility.Visible)
                {
                }
                else
                {
                    double oldleft = HoverContentner.Margin.Left;
                    double oldtop = HoverContentner.Margin.Top;
                    //if (!left && e.DeltaManipulation.Translation.X<0)
                    //{
                    //    oldleft += -e.DeltaManipulation.Translation.X;
                    //}
                    //else
                    //{
                    //    oldleft += e.DeltaManipulation.Translation.X;
                    //}
                    oldleft += e.DeltaManipulation.Translation.X;
                    oldtop += e.DeltaManipulation.Translation.Y;
                   // Debug.WriteLine("左边距"+oldleft + "............... 右边距"+ oldtop);
                    HoverContentner.Margin = new Thickness(oldleft, oldtop, 0, 0);
                    this.UpdateLayout();
                }
            }

      拖动完成后根据位置靠边显示

     private void image0_ManipulationCompleted(object sender, System.Windows.Input.ManipulationCompletedEventArgs e)
            {
                if (e.TotalManipulation.Translation.X==0.0f&&e.TotalManipulation.Translation.Y==0.0f)
                {
                    return;
                }
               // Debug.WriteLine("  HoverContentner.Margin.left: " + HoverContentner.Margin.Left);
                if (left &&HoverContentner.Margin.Left < 220)
                {
                    HoverContentner.Margin = new Thickness(0, HoverContentner.Margin.Top, 0, 0);
                    updateCanvas(true);
                }
                else if (left &&HoverContentner.Margin.Left > 220)
                {
                    HoverContentner.Margin = new Thickness(185, HoverContentner.Margin.Top, 0, 0);
                    updateCanvas(false);
                }
                else if (!left&&HoverContentner.Margin.Left > 0)
                {
                    HoverContentner.Margin = new Thickness(185, HoverContentner.Margin.Top, 0, 0);
                    updateCanvas(false);
                }
                else
                {
                    HoverContentner.Margin = new Thickness(0, HoverContentner.Margin.Top, 0, 0);
                    updateCanvas(true);
                }
            }

      然后更新布局

      private void updateCanvas( bool isleft)
            {
                left = isleft;
                if (isleft)
                {
                 //   trasnlateLength = 60;
                    Canvas.SetLeft(image0, 0);
                    Canvas.SetLeft(image1, 60);
                    Canvas.SetLeft(image2, 120);
                    Canvas.SetLeft(image3, 185);
                    Canvas.SetLeft(image4, 240);
                    border.HorizontalAlignment = HorizontalAlignment.Left;
                    border.RenderTransformOrigin = new Point(0, 0);
                }
                else
                {
                  //  trasnlateLength = -60;
                    Canvas.SetLeft(image0, 240);
                    Canvas.SetLeft(image1, 185);
                    Canvas.SetLeft(image2, 120);
                    Canvas.SetLeft(image3, 60);
                    Canvas.SetLeft(image4, 0);
                    border.HorizontalAlignment = HorizontalAlignment.Right;
                    border.RenderTransformOrigin = new Point(1, 1);
                    HoverContentner.Width = 300;
                    //image1.Visibility = Visibility.Visible;
                    //image2.Visibility = Visibility.Visible;
                    //image3.Visibility = Visibility.Visible;
                    //image4.Visibility = Visibility.Visible;
                    UpdateLayout();
                }
            }

       点击图片时开始执行动画,一个展开的和一个收回的动画,如果上次悬浮窗的位置和这次的位置不同(上次在左边,这次在右边,则更新动画)

           private void image0_Tap(object sender, System.Windows.Input.GestureEventArgs e)
            {
                if (lastleft != left)//如果方向改变则刷新动画
                {
                    expandstory = CreateExpand();
                    hidestory = HideExpand();
                }
                if (isStoryBegin)
                {
                    expandstory.Begin();
                    isStoryBegin = false;
                }
                else
                {
                    hidestory.Begin();
                    isStoryBegin = true;
                }
            }

      展开的动画

           private Storyboard CreateExpand()
            {
                Storyboard expand = new Storyboard();
                #region 旋转动画
                for (int i = 0; i < 5; i++)
                {
                    //旋转动画
                    DoubleAnimationUsingKeyFrames rotation = new DoubleAnimationUsingKeyFrames();
                    Storyboard.SetTargetProperty(rotation, new PropertyPath("(UIElement.RenderTransform).(CompositeTransform.Rotation)"));
                    //只有动画在xaml中才可以使用这个方法
                    // Storyboard.SetTargetName(rotation, "image" + i);
    
                    Storyboard.SetTarget(rotation, this.FindName("image" + i) as Image);
                    EasingDoubleKeyFrame startAngle = new EasingDoubleKeyFrame();
                    startAngle.Value = -360;
                    startAngle.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(0));
                    rotation.KeyFrames.Add(startAngle);
                    if (i == 2)
                    {
                        rotation.BeginTime = TimeSpan.FromMilliseconds(50);
                    }
                    else if (i == 3)
                    {
                        rotation.BeginTime = TimeSpan.FromMilliseconds(100);
                    }
                    else if (i == 4)
                    {
                        rotation.BeginTime = TimeSpan.FromMilliseconds(150);
                    }
                    EasingDoubleKeyFrame endAngle = new EasingDoubleKeyFrame();
                    endAngle.Value = 0;
                    endAngle.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(300));
                    rotation.KeyFrames.Add(endAngle);
                    expand.Children.Add(rotation);
                }
                #endregion
                for (int i = 1; i < 5; i++)
                {
                    #region 平移动画            
                    //X轴平移 
                    DoubleAnimationUsingKeyFrames xtranslate = new DoubleAnimationUsingKeyFrames();
                    Storyboard.SetTargetProperty(xtranslate, new PropertyPath("(UIElement.RenderTransform).(CompositeTransform.TranslateX)"));
                    Storyboard.SetTarget(xtranslate, this.FindName("image" + i) as Image);
                    //起始点
                    EasingDoubleKeyFrame xstartPoint = new EasingDoubleKeyFrame();
                    xstartPoint.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(0));
                    if (i == 1)
                    {
                        xstartPoint.Value = left ? -trasnlateLength : trasnlateLength;            
                    }
                    else if (i == 2)
                    {
                        xtranslate.BeginTime = TimeSpan.FromMilliseconds(50);
                        xstartPoint.Value = left ? -trasnlateLength * 2 : trasnlateLength * 2;   
         
                    }
                    else if (i == 3)
                    {
                        xtranslate.BeginTime = TimeSpan.FromMilliseconds(100);
                        xstartPoint.Value = left ? -trasnlateLength * 3 : trasnlateLength * 3;   
                    }
                    else if (i == 4)
                    {
                        xtranslate.BeginTime = TimeSpan.FromMilliseconds(150);
                        xstartPoint.Value = left ? -trasnlateLength * 4 : trasnlateLength * 4; ; 
                    }
                    lastleft = left;
                    xstartPoint.EasingFunction = new PowerEase() { EasingMode = 0 };
                    //终点
                    EasingDoubleKeyFrame xendPoint = new EasingDoubleKeyFrame();
                    xendPoint.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(300));
                    xendPoint.Value = 0;
                      
                    xendPoint.EasingFunction = new PowerEase() { EasingMode = 0 };
    
                    xtranslate.KeyFrames.Add(xstartPoint);
                    xtranslate.KeyFrames.Add(xendPoint);
                    expand.Children.Add(xtranslate);
                    #endregion
    
                    #region 改变属性值的动画
                    //改变属性值的动画
                    ObjectAnimationUsingKeyFrames visi = new ObjectAnimationUsingKeyFrames();
                    Storyboard.SetTargetProperty(visi, new PropertyPath("(UIElement.Visibility)"));
                    Storyboard.SetTarget(visi, this.FindName("image" + i) as Image);
    
                    DiscreteObjectKeyFrame startObj = new DiscreteObjectKeyFrame();
                    startObj.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(0));
                    startObj.Value = Visibility.Visible;
    
                    DiscreteObjectKeyFrame endObj = new DiscreteObjectKeyFrame();
                    endObj.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(300));
                    endObj.Value = Visibility.Visible;
    
                    if (i == 2)
                    {
                        visi.BeginTime = TimeSpan.FromMilliseconds(50);
    
                    }
                    else if (i == 3)
                    {
                        visi.BeginTime = TimeSpan.FromMilliseconds(100);
                    }
    
                    else if (i == 4)
                    {
                        visi.BeginTime = TimeSpan.FromMilliseconds(150);
    
                    }
                    visi.KeyFrames.Add(startObj);
                    visi.KeyFrames.Add(endObj);
                    expand.Children.Add(visi);
                    #endregion
                }
    
                #region 缩放动画
                //X轴平移 
                DoubleAnimationUsingKeyFrames xtranslateb = new DoubleAnimationUsingKeyFrames();
                Storyboard.SetTargetProperty(xtranslateb, new PropertyPath("(UIElement.RenderTransform).(CompositeTransform.ScaleX)"));
                Storyboard.SetTarget(xtranslateb, this.FindName("border" ) as Border);
                //起始点
                EasingDoubleKeyFrame xstartPointb = new EasingDoubleKeyFrame();
                xstartPointb.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(0));
               
                
                xstartPointb.Value = 0.04f;
              
                xstartPointb.EasingFunction = new PowerEase() { EasingMode = 0 };
                //终点
                EasingDoubleKeyFrame xendPointb = new EasingDoubleKeyFrame();
                xendPointb.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(300));
                xendPointb.Value = 1;
    
                xendPointb.EasingFunction = new PowerEase() { EasingMode = 0 };
    
                xtranslateb.KeyFrames.Add(xstartPointb);
                xtranslateb.KeyFrames.Add(xendPointb);
                expand.Children.Add(xtranslateb);
                #endregion
    
                #region 改变border属性值的动画
                //改变属性值的动画
                ObjectAnimationUsingKeyFrames visib = new ObjectAnimationUsingKeyFrames();
                Storyboard.SetTargetProperty(visib, new PropertyPath("(UIElement.Visibility)"));
                Storyboard.SetTarget(visib, this.FindName("border") as Border);
    
                DiscreteObjectKeyFrame startObjb = new DiscreteObjectKeyFrame();
                startObjb.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(0));
                startObjb.Value = Visibility.Visible;
    
                DiscreteObjectKeyFrame endObjb = new DiscreteObjectKeyFrame();
                endObjb.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(300));
                endObjb.Value = Visibility.Visible;
    
               
                visib.KeyFrames.Add(startObjb);
                visib.KeyFrames.Add(endObjb);
                expand.Children.Add(visib);
                #endregion
                return expand;
            }

      还有个收缩的动画就不给大家贴出来了,留给大家一个自己动手的过程。哇咔咔,下面贴张动态图,吸引下诸位眼球。

  • 相关阅读:
    石子游戏2
    礼物的最大价值
    CF512D. Fox And Travelling
    arc099F
    CF504E. Misha and LCP on Tree(长链剖分求k级祖先)
    agc031D
    CF555E. Case of Computer Network
    agc023D
    CF1406E. Deleting Numbers
    CF585F. Digits of Number Pi
  • 原文地址:https://www.cnblogs.com/blog-wanghao/p/4253819.html
Copyright © 2020-2023  润新知