Windows Phone中懸浮小助手的製做過程

前言canvas

     看到過其餘平臺遊戲中第三方sdk的一些懸浮的小助手,近來無聊,就作個玩兒,看着比較簡單,作起來仍是花費了很多力氣。ide

開始佈局

  首先是頁面的xaml代碼,其實比較簡單,就是一些Canvas裏面裝了些image和一個border(是做爲按鈕展開後的背景)。下面註釋的那個canvas是爲了看到懸浮窗在界面右邊的時的效果,方便作動畫添加的,讀者不用在乎動畫

  要求懸浮按鈕能夠拖動,拖動後靠在自動屏幕邊上顯示,拖動的時候超過屏幕的中軸就靠在右邊,點擊按鈕向左邊以此展開按鈕,若是拖動後在屏幕中軸左邊則靠左側邊上,點擊屏幕向右依次展開,再次點擊收回按鈕。(展開按鈕的時候我有添加了個選擇動畫,旋轉了360度,)考慮到動畫須要變化,之前懸浮窗的中的按鈕位置也要根據拖放的位置動態變化,因此動畫和佈局都用代碼控制。this

 

 <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>

 

  一些定義的變量spa

        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;

  首先是處理拖動的代碼code

    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();
            }
        }

  拖動完成後根據位置靠邊顯示orm

 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);
            }
        }

  而後更新佈局blog

  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;
        }

  還有個收縮的動畫就不給你們貼出來了,留給你們一個本身動手的過程。哇咔咔,下面貼張動態圖,吸引下諸位眼球。

相關文章
相關標籤/搜索