简体   繁体   中英

WPF - Create a floating animated clickable control (image or…)

在此输入图像描述 I want create a floating animated clickable control like a helium balloon that moves sometimes to right or left too in my WPF application.

The helium balloons likes go up! but also they moves right or left if we tap on them or by wind.

In advance cases, sometimes they turn to right or left

.................................. 在此输入图像描述在此输入图像描述在此输入图像描述 ..................................

So i searched the web but i didn't find any usefull sample project or library or styles.

  • How i can create style and animation in WPF to show an image or control buoyant or suspended in air.?

  • Have you any suggestions to implement this idea simply...?

Edit:

  • What is your suggestion for a random and infinite smooth turns to right and left . for example 51degrees to left then 163degree to right and.... i want keep my balloon in my window and often top of the window .

Edit:

I created an animation base on these answers but more complex by manipulating them and adding multiple parallel animation on balloon image and its container. ;) Thanks all...

Now my primary result is like this: 在此输入图像描述

You can achieve this with a DoubleAnimation and a RotateTransform like @Ega mentioned. To answer your "random and infinite" turns to right and left, here's how you could do it (it's very basic but does the job).

    private async void Button_Click(object sender, RoutedEventArgs e)
    {
        var rnd = new Random();
        var direction = -1;

        while (true)
        {
            var percent = rnd.Next(0, 100);
            direction *= -1; // Direction changes every iteration
            var rotation = (int)((percent / 100d) * 45 * direction); // Max 45 degree rotation
            var duration = (int)(750 * (percent / 100d)); // Max 750ms rotation

            var da = new DoubleAnimation
            {
                To = rotation,
                Duration = new Duration(TimeSpan.FromMilliseconds(duration)),
                AutoReverse = true // makes the balloon come back to its original position
            };

            var rt = new RotateTransform();
            Balloon.RenderTransform = rt; // Your balloon object
            rt.BeginAnimation(RotateTransform.AngleProperty, da);

            await Task.Delay(duration * 2); // Waiting for animation to finish, not blocking the UI thread
        }
    }

edit for .NET 3.5

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var thread = new Thread(this.AnimateBalloon);
        thread.Start();
    }

    public void AnimateBalloon()
    {
        var rnd = new Random();
        var direction = -1;

        while (true)
        {
            var percent = rnd.Next(0, 100);
            direction *= -1; // Direction changes every iteration
            var rotation = (int)((percent / 100d) * 45 * direction); // Max 45 degree rotation
            var duration = (int)(750 * (percent / 100d)); // Max 750ms rotation

            Balloon.Dispatcher.BeginInvoke(
                (Action)(() =>
                {
                    var da = new DoubleAnimation
                    {
                        To = rotation,
                        Duration = new Duration(TimeSpan.FromMilliseconds(duration)),
                        AutoReverse = true // makes the balloon come back to its original position
                    };

                    var rt = new RotateTransform();
                    Balloon.RenderTransform = rt; // Your balloon object
                    rt.BeginAnimation(RotateTransform.AngleProperty, da);
                }));

            Thread.Sleep(duration * 2);
        }
    }

Farseer Physics Engine for C# will allow you to create a real world simulation. You can control gravity, inertia, force and even other physical stuff.

    World world = new World(new Vector2(0f, 9.82f));
    //We create a body object and make it dynamic (movable)
    Body myBody = world.CreateBody();
    myBody.BodyType = BodyType.Dynamic;

    //We create a circle shape with a radius of 0.5 meters
    CircleShape circleShape = new CircleShape(0.5f);

    //We fix the body and shape together using a Fixture object
    Fixture fixture = myBody.CreateFixture(circleShape);

For this scenario you may need to create a world with less gravity and objects will fly. You can apply force from either side of the object to move it.

in C# DoubleAnimation is a powerful Class Support Animation inside System.Windows.Media.Animation; NameSpace so this class have some Methods and Properties let me to tell you it

DoubleAnimation ANobj = new DoubleAnimation();//make object from DoubleAnimation
ANobj.From=0 //the 0 is point you want to star animation
ANobj.To=270//the end pont of moving 
// that values  is dependent on your self as you want
ANobj.Duration = new Duration(TimeSpan.FromSeconds(60)); //specify the duration of moving 
ANobj.RepeatBehavior = RepeatBehavior.Forever;//RepeatBehavior as you want

also use RotateTransform class to Rotate C# Componets in WPF

RotateTransform RTobj=new RotateTransform();//make object from RotateTransform
RTobj.CenterX = 277;//X point of your Element(Componet)
RTobj.CenterY = 245;//Y point of your Element(Componet)
RTobj.Angle = 360;//angle between 
RTobj.BeginAnimation(RotateTransform.AngleProperty,ANobj);

also after doing that configures set this obj to RenderTransform property from your Element like it

yourElementName.RenderTransform=RTobj

if you want read more at MSDN about System.Windows.Media.Animation

Here is one I did in high school. Probably very outdated now but just for interest sake.

//the animation thread
        System.Threading.Thread thr;

        thr = new System.Threading.Thread(annimate);
        thr.Start();

the animation method

 void annimate()
    {     
        try
        {       
            double angleToAnimateTo = 20;
            double CurrentAngle = 0;
            bool increment = false;

            while (IsAnimating)
            {
                if (increment)
                    CurrentAngle++;
                else
                    CurrentAngle--;

                if (CurrentAngle == angleToAnimateTo )
                    increment = false;

                if (CurrentAngle == (angleToAnimateTo * -1))
                    increment = true;


                this.Dispatcher.Invoke((Action)(() =>
                {
                    this.imgBallon.RenderTransform = new RotateTransform(CurrentAngle);
                }));

                System.Threading.Thread.Sleep(100);
            }


        }
        catch (Exception e)
        {
            MessageBox.Show(e.Message);
        }

imgBalloon is a simple image in wpf. Here is the xaml..

<Image x:Name="imgBallon" 
        Source="/img/balloon_blue.png" Width="50"> </Image>

May This help You Here,I take polygon and One image to left to right you can set by Your choice :)

<Window x:Class="Animation.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="XAML Animation - Spinning Stars" Height="300" Width="355"
        >
        <Grid Name="myGrid">
          <Canvas Margin="15,18,18,26" MinHeight="50" MinWidth="50" Name="canvas1">
            <!-- Invisible element just to host composite transform -->
            <Polygon
                Name ="mypolygon1"

                Stroke="Blue"

                StrokeThickness="1.0"

                Points="176.5,50 189.2,155.003 286.485,113.5 201.9,177 286.485,240.5 

        189.2,198.997 176.5,304 163.8,198.997 66.5148,240.5 151.1,177 

        66.5148,113.5 163.8,155.003">

              <Polygon.RenderTransform>
                <TransformGroup>
                  <RotateTransform x:Name="xformRotate" CenterX="176" CenterY="145" />
                  <TranslateTransform x:Name="xformTranslate" X ="-50" Y="-50" />
                  <ScaleTransform x:Name ="xformScale" ScaleX=".25" ScaleY=".25" />
                </TransformGroup>
                </Polygon.RenderTransform>

              <Polygon.Fill>

                  <SolidColorBrush Color="Blue">
                      <!--<ColorAnimation From="Yellow" To="Blue" Duration="7"

                        RepeatCount="500" AutoReverse="True"/>-->

                  </SolidColorBrush>

                </Polygon.Fill>
                <Polygon.Triggers>
                  <EventTrigger RoutedEvent="Polygon.Loaded">
                    <EventTrigger.Actions>
                      <BeginStoryboard>
                      <Storyboard>
                        <!-- RotateTransform angle from 0 to 360, repeated -->
                        <DoubleAnimation Storyboard.TargetName="xformRotate"
                                         Storyboard.TargetProperty="Angle"
                                         From="0" To="360" Duration="0:0:01"
                                         RepeatBehavior="Forever" />
                        <DoubleAnimation Storyboard.TargetName="xformTranslate"
                                         Storyboard.TargetProperty="X"
                                         From="1" To="750" Duration="0:0:14"
                                         AutoReverse ="True" RepeatBehavior="Forever" />
                      </Storyboard>
                      </BeginStoryboard>
                    </EventTrigger.Actions>
                  </EventTrigger>
                  </Polygon.Triggers>

              </Polygon>
            <Polygon
                Name ="mypolygon2"

                Stroke="Red"

                StrokeThickness="1.0"

                Points="176.5,50 189.2,155.003 286.485,113.5 201.9,177 286.485,240.5 

        189.2,198.997 176.5,304 163.8,198.997 66.5148,240.5 151.1,177 

        66.5148,113.5 163.8,155.003">

              <Polygon.RenderTransform>
                <TransformGroup>
                  <RotateTransform x:Name="xformRotateIt"   CenterX="176" CenterY="145"  />
                  <ScaleTransform ScaleX=".25" ScaleY=".25" />
                  <TranslateTransform  x:Name="xformTranslateIt" X="0" Y="100" />
                </TransformGroup>
              </Polygon.RenderTransform>

              <Polygon.Fill>

                <SolidColorBrush x:Name ="mybrush" Color="Red" />
              </Polygon.Fill>
              <Polygon.Triggers>
                <EventTrigger RoutedEvent="Polygon.Loaded">
                  <EventTrigger.Actions>
                    <BeginStoryboard>
                      <Storyboard x:Name="myStoryBoard" Completed="OnCompletedAnimation">
                        <!-- RotateTransform angle from 0 to 360, repeated -->
                        <DoubleAnimation Storyboard.TargetName="xformRotateIt"
                                         Storyboard.TargetProperty="Angle"
                                         From="0" To="360" Duration="0:0:01"
                                         RepeatBehavior="Forever" />
                        <DoubleAnimation Storyboard.TargetName="xformTranslateIt"
                                         Storyboard.TargetProperty="X"
                                         From="1" To="100" Duration="0:0:14"
                                         AutoReverse ="True" RepeatBehavior="Forever" />
                        <ColorAnimation Storyboard.TargetName="mybrush" Storyboard.TargetProperty="Color" From="Red" To="Blue" Duration="0:0:7" 
                        RepeatBehavior="Forever" AutoReverse="True"/>
                      </Storyboard>
                    </BeginStoryboard>
                  </EventTrigger.Actions>
                </EventTrigger>
              </Polygon.Triggers>

            </Polygon>


            <Image Margin="75,61,0,119" Name="image1" Source="Images\KENNY.bmp" HorizontalAlignment="Left" Width="72">
              <Image.RenderTransform>
                <TransformGroup>
                  <RotateTransform x:Name="KennyRotateIt"   CenterX="50" CenterY="50" Angle="45"  />
                  <ScaleTransform x:Name="KennyScaleIt" ScaleX=".75" ScaleY=".75" />
                  <TranslateTransform  x:Name="KennyTranslateIt" X="0" Y="100" />
                </TransformGroup>
              </Image.RenderTransform>
              <Image.Triggers>
                <EventTrigger RoutedEvent="Image.Loaded">
                  <EventTrigger.Actions>
                    <BeginStoryboard>
                      <Storyboard x:Name="myStoryBoard1" Completed="OnCompletedAnimation">
                        <!-- RotateTransform angle from 0 to 360, repeated -->
                        <DoubleAnimation Storyboard.TargetName="KennyRotateIt"
                                         Storyboard.TargetProperty="Angle"
                                         From="0" To="360" Duration="0:0:01"
                                         RepeatBehavior="Forever" />
                        <DoubleAnimationUsingKeyFrames
                             Storyboard.TargetName="KennyTranslateIt"
                             Storyboard.TargetProperty="X"
                             Duration="0:0:10" AutoReverse="True" RepeatBehavior="Forever">

                          <!-- These KeyTime properties are specified as TimeSpan values 
                     which are in the form of "hours:minutes:seconds". -->
                          <LinearDoubleKeyFrame Value="10" KeyTime="0:0:3" />
                          <LinearDoubleKeyFrame Value="100" KeyTime="0:0:5" />
                          <LinearDoubleKeyFrame Value="200" KeyTime="0:0:10" />
                        </DoubleAnimationUsingKeyFrames>
                        <!-- DoubleAnimation Storyboard.TargetName="KennyTranslateIt"
                                         Storyboard.TargetProperty="X"
                                         From="-50" To="100" Duration="0:0:14"
                                         AutoReverse ="True" RepeatBehavior="Forever" / -->
                      </Storyboard>
                    </BeginStoryboard>
                  </EventTrigger.Actions>
                </EventTrigger>
              </Image.Triggers>
            </Image>
          </Canvas>
      </Grid>

            </Window>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM