前言

     看到过其他平台游戏中第三方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;
        }

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

你可能感兴趣的内容
0条评论

dexcoder

这家伙太懒了 <( ̄ ﹌  ̄)>
Owner