tags:

views:

292

answers:

3

I'm developing a form in WPF with the technique of Parallax Scrolling and I need to work out one last step. I wish recreate this nice effect of the mouse.

I'm trying to get the cool delayed easing when the mouse finishes moving. When the mouse finishes moving, the background slowly stops moving a bit later, which is easily achievable via the easing of points, but I don't have a clear idea on how do it.

I created 3 backgrounds and when the mouse moves, I recreate Parallax Scrolling. Now I wish add this feature to make it all more realistic.

Do you have any idea how I can recreate this effect of the mouse?

EDIT

I list my code snippet to show you how I move the 3 backgrounds when the mouse move event:

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;

    }

Maybe that can make you understand my question better.

+1  A: 

You basically need to introduce a concept of velocity.

When you start moving the mouse, you need to not just "follow the mouse", but rather use the mouse's movement and speed to create a velocity by which you'll move. You can then have a timer that does the movement.

When the mouse stops, you'll have a velocity. Your timer can then just keep the movement based off the current velocity, and let the velocity reduce quickly based off some dampening rate. This will give the effect of it slowing down.

Reed Copsey
problem with his approach is that it might go out of sync. His example clearly shows that the background is locked (although at a slower pace) to the mouse position
Toad
I've done this kind of thing by mapping acceleration to the Sin curve. A little trig can get the shape of the curve how you want it (from 0 to 1 instead of -1 to 1, etc) gives you a value you can use to smoothly decrease your velocity slower as you near 0.
Will
the tricky part is that the mouse can start moving again at any point.... to get the background accelerating once again using your sin approach is difficult since it could be halfway the delaying sin, while it again has to accelerate again. Take a look at my approach(other answer) which is much simpler and works in these cases too
Toad
+1  A: 

It's very easy:

Suppose in mouseX and mouseY are the actual mouse values. Then the background should for instance move to backX, backY which could be something like:

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

But to get the nice fluid movement you don't set the variable directly but do it like this:

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

And for every frame (30 frames per second or faster) we calculate the background position at this time:

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

The Delay can be set anywhere between 2 and 16. The higher the value, the slower it follows your movements.

Toad
Hi Reineir thanks for your respone ,i wish know what do you refer with destBack?Thanks so much
JayJay
destbacklx and destbacky are the coordinates the background should eventually move to. backx and backy are the coordinates the background currently is at. Every frame it is edging towards it's destination coordinates (destbackx and destbacky)
Toad
i just saw your edit... the place where you fill out the translate.x and translate.y position you are basically setting the position of the background. Now instead of doing this directly, put these values in destBsckX and destBackY (just some variables you declare). Now add a timer function (30 times a second) and add the last 2 lines of my example in it. Instead of backX and backY from my example, you use translate.x and translate.y. For all other layers you take the same approach, just start with one of the backgroundlayers first to get it right
Toad
HI renier i tried to follow your way but i cannot work out that ,i keep in stuck to add a timer fuction.Cheers
JayJay
look at this short article om how to add a timer function. http://www.codeguru.com/csharp/sample_chapter/article.php/c7763/ the second listing is what I mean with a timer function. I would set the delay at 30 or 50. In the callback of the timer you'll be updating the transforms of your background
Toad
Hi renier with my poor knowledge about C# i could not work out my feature , ic annot recreate that effect mouse that i like.i will try yet buit i will thanks you for your care untill now.;)
JayJay
jayjay: what you can do is start easier: let something (a circle for instance) trail your mouse with the same easein movement. The idea is the same: in the mouse event you set: destBallX = mouseX and destBallY is mouseY. (destBallX and destBallY are variables in your class). in the timer function you blit the actual ballon the position ballX and ballY. These coordinates you calc as following: ballX += (destBallX - ballX) / 4; (and same for Y). See if you can get thisd working first so you understand the principle. succes!
Toad
+1  A: 

Hey,

try this, there is a Timer that call repeatly your mouseMove method that i Modified just a bit to call the GetPos Method that actually return a delayed mousePos.

this should get you started.

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

}
Dave3D
Hey Dave your code snippet is so right .I can reproduce the same mouse effect of the link above!!!Thanks so much Dave and have a happy day
JayJay
thanks, great to hear that, JayJay !
Dave3D