我如何重新创建这个MouseMove效果?

时间:2009-10-15 17:48:45

标签: c# .net wpf mouseevent

我正在使用Parallax Scrolling技术在WPF中开发一个表单,我需要完成最后一步。我希望重新创建this nice effect of the mouse

当鼠标完成移动时,我正试图获得很酷的延迟缓和效果。当鼠标完成移动时,背景会稍微停止移动,这可以通过缓和点来轻松实现,但我对如何做到这一点并不清楚。

我创建了3个背景,当鼠标移动时,我重新创建了Parallax Scrolling。现在我希望添加此功能以使其更加真实。

你知道如何重建这种鼠标效果吗?

修改

我列出了我的代码片段,向您展示了当鼠标移动事件时我如何移动3个背景:

private void Window_MouseMove(object sender, MouseEventArgs e)//it is the Layout Root that contain the 3 layouts to create the parallax effect
    {
        Point mouse = e.GetPosition(this);

        TransformGroup group = (TransformGroup)this.grid.RenderTransform; //The first Background

        TranslateTransform translate = (TranslateTransform)group.Children[3];

        translate.X = 400 - mouse.X ;

        translate.Y = 300 - mouse.Y;


        TransformGroup group1 = (TransformGroup)this.grid1.RenderTransform;// 2th Background

        TranslateTransform translate1 = (TranslateTransform)group1.Children[3];

        translate1.X = 400 - (mouse.X - 10) * 2;

        translate1.Y = 300 - (mouse.Y - 10) * 2;


        TransformGroup group2 = (TransformGroup)this.grid2.RenderTransform;// 3th Background

        TranslateTransform translate2 = (TranslateTransform)group2.Children[3];

        translate2.X = 400 - (mouse.X - 20) * 3;

        translate2.Y = 300 - (mouse.Y - 20) * 3;

    }

也许这可以让你更好地理解我的问题。

3 个答案:

答案 0 :(得分:2)

试试这个,有一个Timer重复调用你的mouseMove方法 我修改了一点来调用实际返回延迟mousePos的GetPos方法。

这应该让你开始。

    public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();
        this.Loaded += new RoutedEventHandler(Window1_Loaded);
    }

    private void Window1_Loaded(object sender, RoutedEventArgs e)
    {
        System.Windows.Threading.DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer( System.Windows.Threading.DispatcherPriority.Render);
        dispatcherTimer.Tick += new EventHandler(DispatcherTimer_Tick);
        dispatcherTimer.Interval = new TimeSpan(0,0,0,0,15);
        dispatcherTimer.Start();
    }

    double precision = 0.025;

    Point GetPos (Point pt, Point target, double speed) 
    { 
        double xdif = target.X-pt.X; 
        double ydif = target.Y-pt.Y; 
        if (xdif>=-precision && xdif<=precision)    pt.X = target.X;
        else                                        pt.X += (target.X-pt.X)*speed; 

        if (ydif>=-precision && ydif<=precision)    pt.Y = target.Y;    
        else                                        pt.Y += (target.Y-pt.Y)*speed;  
        return  pt; 
    }

    double speed                                        = 0.1;
    Point mouse = new Point();
    private void DispatcherTimer_Tick(object sender, EventArgs e)
    {
        Point mousePos                                  = Mouse.GetPosition(this); // change 'this' to a transparent element over your view if needed
        mouse = GetPos (mouse, mousePos, speed);

        TransformGroup group = (TransformGroup)this.grid.RenderTransform; 
        TranslateTransform translate = (TranslateTransform)group.Children[3];
        translate.X = 400 - mouse.X ;
        translate.Y = 300 - mouse.Y;

        TransformGroup group1 = (TransformGroup)this.grid1.RenderTransform;
        TranslateTransform translate1 = (TranslateTransform)group1.Children[3];
        translate1.X = 400 - (mouse.X - 10) * 2;
        translate1.Y = 300 - (mouse.Y - 10) * 2;

        TransformGroup group2 = (TransformGroup)this.grid2.RenderTransform;// 3th Background
        TranslateTransform translate2 = (TranslateTransform)group2.Children[3];
        translate2.X = 400 - (mouse.X - 20) * 3;
        translate2.Y = 300 - (mouse.Y - 20) * 3;
    }

}

答案 1 :(得分:1)

你基本上需要引入速度概念。

当你开始移动鼠标时,你不仅需要“跟随鼠标”,而是使用鼠标的移动和速度来创建一个你移动的速度。然后,您可以使用计时器进行移动。

当鼠标停止时,你将拥有一个速度。然后,您的计时器可以根据当前速度保持运动,并根据一些阻尼率让速度快速降低。这会减慢它的效果。

答案 2 :(得分:1)

这很容易:

假设在mouseX和mouseY中是实际的鼠标值。然后背景应该移动到backX,backY可能是这样的:

 backX = -mouseX/2;    //background moves in opposite direction and with half the speed of the mouse
 backY = -mouseY/2;

但要获得漂亮的流体运动,你不要直接设置变量,而是这样做:

 destBackX = -mouseX/2;  //actual position we want the background to move to
 destBackY = -mouseY/2;

对于每一帧(每秒30帧或更快),我们计算此时的背景位置:

 backX += (destBackX - backX)/DELAY;   //backX is now eased to the final position destBackX
 backY += (destBackY - backY)/DELAY;

延迟可以设置在2到16之间。值越高,跟随你的移动就越慢。