2009-10-15 73 views
2

我正在使用视差滚动技术在WPF中开发一个表单,我需要制定出最后一步。我希望重新创建this nice effect of the mouse如何重新创建此MouseMove效果?

我试图让鼠标完成移动时很酷的延迟缓动。当鼠标移动完毕后,背景会慢慢停止移动,这很容易通过点的放松来实现,但我不清楚它是如何实现的。

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

你有什么想法我可以重新创建鼠标的这种效果吗?

编辑

我列出我的代码片段来告诉你我是如何移动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; 

    } 

也许可以让你明白我的问题更好。

回答

2

试试这个,有个重复调用你的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; 
    } 

} 
+0

嘿戴夫你的代码片段是如此正确。我可以重现上面的链接相同的鼠标效果! 非常感谢戴夫,祝你有个愉快的日子 – JayJay 2009-10-18 09:54:45

+0

非常感谢JayJay! – Dave3D 2009-10-18 16:06:03

1

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

当您开始移动鼠标时,您不仅需要“遵循鼠标”,而是需要使用鼠标的移动和速度来创建移动的速度。然后你可以有一个定时器来完成移动。

当鼠标停止时,您将获得速度。然后,您的计时器可以保持基于当前速度的运动,并根据某种衰减速度快速减小速度。这会给它减速的效果。

+0

他的方法的问题是它可能不同步。他的例子清楚地表明背景被锁定(尽管速度较慢)到鼠标位置 – Toad 2009-10-15 18:00:59

+0

我已经通过将加速度映射到Sin曲线来完成这种事情。一个小三角可以得到你想要的曲线形状(从0到1而不是-1到1等)给你一个值,你可以使用它来平滑地减慢你的速度,当你接近0时更慢。 – Will 2009-10-15 18:06:31

+0

棘手的部分就是鼠标可以在任何时候再次开始移动......使用你的罪过方法再次获得背景加速是困难的,因为它可能是拖延的罪的一半,而它又一次需要再次加速。看看我的方法(其他答案),这是更简单,在这些情况下也起作用 – Toad 2009-10-15 18:18:46

1

这很容易:

假设在鼠标X和鼠标Y是实际的鼠标值。那么背景应该为实例移动到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更高之间的任何位置设置的值,第慢慢跟随你的动作。

+0

您好Reineir感谢您的答复,我希望知道你指的是什么与destBack? 非常感谢 – JayJay 2009-10-16 06:51:46

+0

destbacklx和destbacky是背景应该最终转移到的坐标。 backx和backy是当前背景的坐标。每个框架都朝着它的目的地坐标(destbackx和destbacky) – Toad 2009-10-16 07:08:13

+0

我刚刚看到您的编辑...您填写translate.x和translate.y位置的位置基本上是设置背景的位置。现在不要直接这样做,把这些值放在destBsckX和destBackY(只是你声明的一些变量)。现在添加一个定时器功能(每秒30次),并添加我的示例的最后2行。我的例子中没有backX和backY,而是使用translate.x和translate.y。对于所有其他层次,您采用相同的方法,首先从其中一个背景图层开始,以便正确地获取它 – Toad 2009-10-16 07:25:36

相关问题