为什么创建非情节提要动画不流畅 [英] Why creating non storyboard animation is not smooth

查看:94
本文介绍了为什么创建非情节提要动画不流畅的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要创建一个动画,当用户滚动时,按钮会根据滚动方向向右或向左移动动画。我需要对该动画进行大量控制,因为在动画进行过程中用户可能会滚动。结果,我决定不使用情节提要来创建自己的动画。这是我制作动画的工作:

I need to create an animation that when the user scrolls then a button animates right or left depeing on the direction of the scroll. I need to have a lot of control over this animation because the user may scroll meanwhile the animation is taking place. as a result I decided to create my own animation without using a storyboard. this is what I did to create my animation:

物品类

class Item : INotifyPropertyChanged
{
    Thickness _M;
    public Thickness M
    {
        get
        {
            return _M;
        }
        set
        {
            _M = value;
            OnPropertyChanged("M");
        }
    }

    // properties needed to animate the control
    public double MarginLeft
    {
        get
        {
            return _M.Left;
        }
        set
        {
            _M.Left = value;
            OnPropertyChanged("M");
        }
    }

    // implement INotifyPropertyChanged interface
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    // the control that we will be animating
    public Button Btn { get; set; }

    //Constructor that takes care of initializing the button and then setting
    // a binding so that we could update the button's position on separate threads
    public Item()
    {
        Binding b = new Binding("M")
        {
            Source = this
        };

        Btn = new Button()
        {
            HorizontalAlignment = HorizontalAlignment.Left,
            VerticalAlignment = VerticalAlignment.Top,
            Width = 100,
            Height = 30           
        };

        Btn.SetBinding(Button.MarginProperty, b);

    }


    double x = 0;
    volatile int threadCounter = 0;
    object _rightLock = new object();

    // method to animate the button
    public void MoveHorizontaly(double speed)
    {
        x += speed;
        threadCounter++;

        Task.Factory.StartNew(() =>
        {
            lock (_rightLock)
            {
                while (Math.Abs(x) > .3)
                {
                    MarginLeft += x;
                    x *= .97;
                    Thread.Sleep(2);
                    if (threadCounter > 1) // if a new animation will take place exit from this one
                        break;
                }

                threadCounter--;
            }
        });
    }

}

主窗口xaml:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded" PreviewMouseWheel="Window_PreviewMouseWheel">
    <Grid>
        <Grid Height="241" Margin="12,58,12,0" Name="grid1" VerticalAlignment="Top" Background="#FFFF9999"></Grid>
    </Grid>
</Window>

后面的主窗口代码:

public partial class MainWindow : Window
{

    Item item1 = new Item();
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        grid1.Children.Add(item1.Btn);
    }

    // event that fires when user scrolls on the main window
    private void Window_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
    {
        item1.MoveHorizontaly(e.Delta/50);
    }


}

我该如何改善这个动画?并没有那么糟,但在情节提要板上创建的动画更加流畅...

推荐答案

就像用复杂的方法制作动画一样。这样的东西会更好?

It seems kind of like a convoluted way to do an animation. Something like this would work better?

Xaml

    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:app="clr-namespace:WpfApplication1"
            Title="MainWindow" Height="350" Width="525" PreviewMouseWheel="Window_PreviewMouseWheel">
        <Grid>
            <Grid Height="241" Margin="12,58,12,0" Name="grid1" VerticalAlignment="Top" Background="#FFFF9999">
                <Button Content="Test" Height="20" Width="60">
                    <Button.RenderTransform>
                        <TranslateTransform x:Name="_transform" />
                    </Button.RenderTransform>
                </Button>
            </Grid>
        </Grid>
    </Window>

后面的代码

public partial class MainWindow : Window
{
    DoubleAnimation _animation;

    public MainWindow()
    {
        InitializeComponent();
        _animation = new DoubleAnimation();
        _animation.Duration = new Duration(TimeSpan.FromMilliseconds(150));
        _animation.FillBehavior = FillBehavior.HoldEnd;
    }

    private void Window_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
    {
        double x = _transform.X;
        _transform.BeginAnimation(TranslateTransform.XProperty, null);
        _transform.SetValue(TranslateTransform.XProperty, x);

        _animation.To = _transform.X + (e.Delta / 2);
        _transform.BeginAnimation(TranslateTransform.XProperty, _animation);
    }
}

这篇关于为什么创建非情节提要动画不流畅的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆