WPF - 创建浮动动画可点击控件(图像或...)

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

我想创建一个 浮动动画可点击 控件,就像在我的 WPF 应用程序中有时也会向右或向左移动的氦气球。

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

..............................................

所以我在网上搜索但没有找到任何有用的示例项目或库或样式。

编辑:


编辑:

我根据这些答案创建了一个动画,但通过操纵它们并在气球图像及其容器上添加多个并行动画而变得更加复杂。 ;) 谢谢大家...

现在我的初步结果是这样的:

在 C# 中 DoubleAnimation 是一个强大的 Class 在 System.Windows.Media.Animation; 命名空间中支持动画 所以这个 class 有一些方法和属性让我告诉你它

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

还可以使用 RotateTransform class 在 WPF 中旋转 C# 组件

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

同样在执行此操作后,将此对象从您的元素中设置为 RenderTransform 属性 喜欢它

yourElementName.RenderTransform=RTobj

如果您想在 MSDN 阅读更多关于 System.Windows.Media.Animation

这是我在高中做的。现在可能已经过时了,但只是为了兴趣。

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

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

动画方法

 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 是 wpf 中的一个简单图像。这是 xaml..

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

这对你有帮助在这里,我从左到右拍摄多边形和一张图片,你可以根据自己的选择进行设置:)

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

您可以像@Ega 提到的那样使用 DoubleAnimationRotateTransform 来实现。要回答您的 "random and infinite" 向右和向左转弯,您可以按照以下方法进行操作(非常基本但可以完成工作)。

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

编辑 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# 将允许您创建真实世界的模拟。你可以控制重力、惯性、力甚至其他物理东西。

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

对于这种情况,您可能需要创建一个重力较小且物体会飞的世界。您可以从对象的任一侧施加力来移动它。