Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
Ulb

drag an MC along a motion guide line

Recommended Posts

Hi All,

 

I want to create a button that is dragged using the "startdrag" across a motionpath tween but the line isnt straight. Is there a way. I have attached an example of what the line will look like.

 

post-14413-0-64454800-1364353234_thumb.jpg

 

Any help would be great

Share this post


Link to post
Share on other sites

Hi and welcome to the GreenSock forums.

 

No there isn't a way with startDrag, because with startDrag you wouldn't be able to make the object stick to the path. startDrag only allows you to constrain the drag to a rectangle.

 

Also, there is no way of using Flash's Motion Guide layers that I'm aware of for this purpose.

 

Fortunately our animation tools to provide enough features to make this possible.

 

The basic concept is

  1. Create a Bezier tween with curviness = 0 that animates your object thru all the points on the path
  2. Create a mechanism that allows for mouseX position to be translated to the Bezier tween's progress() value while the user's mouse button is down (dragging).

In essence you are creating an invisible scrubber that allows the user to control the progress of the tween.

 

You can see it in action here: http://snorkl.tv/dev/pathDrag/

 

The implementation is not so trivial

 

 

import com.greensock.*;
import com.greensock.easing.*;
import com.greensock.plugins.*;
import flash.events.MouseEvent;
import flash.geom.Rectangle;


TweenPlugin.activate([bezierPlugin]);


var startMouseX;


//create bezier tween based on position of dots on the stage
var tween:TweenMax = TweenMax.to(btn, 4, {bezier:{values:[
   {x:d1.x,y:d1.y},
   {x:d2.x,y:d2.y},
   {x:d3.x,y:d3.y},
   {x:d4.x,y:d4.y},
   {x:d5.x,y:d5.y},
   ],
   type:"thru",
   curviness:0
   },
   ease:Linear.easeNone,
   paused:true
   });
   
btn.buttonMode = true;   
btn.addEventListener(MouseEvent.MOUSE_DOWN, downHandler);
btn.addEventListener(MouseEvent.MOUSE_UP, upHandler);




function downHandler(e:MouseEvent):void {
//an offset value that later lets us translate the mouse position to a progress() value
startMouseX = mouseX - (btn.x - (btn.width/2));
stage.addEventListener(MouseEvent.MOUSE_MOVE, update);
stage.addEventListener(MouseEvent.MOUSE_UP, upHandler);
}


function upHandler(e:MouseEvent):void {
stage.removeEventListener(MouseEvent.MOUSE_MOVE, update);
stage.removeEventListener(MouseEvent.MOUSE_UP, upHandler);
}


function update(e:Event):void {
//took some guesswork but it seems to do the trick
tween.progress(Math.max((mouseX-startMouseX)/(d5.x-startMouseX), 0));
}
 

 

pathDrag_cs5.zip

Share this post


Link to post
Share on other sites

Thanks Carl, I've copied the code and tried to get it working but get an error 1061: Call to a possibly undefined method progress through a reference with static type com.greensock:TweenMax. The error is referring to the update function. I am using the code in a class file because I am trying to code using OOP more and more but i can't see why its having the issue. Below is the code from my file, am i doing something wrong? 

 

package  
{
	import flash.display.MovieClip;
	import com.greensock.*;
	import com.greensock.easing.*;
	import com.greensock.plugins.*;
	import flash.events.Event;
	import flash.events.MouseEvent;

	TweenPlugin.activate([bezierPlugin]);
	
	public class motionguide extends MovieClip 
	{
		public var startMouseX;
		//create bezier tween based on position of dots on the stage
		public var tween:TweenMax = TweenMax.to(draggerMc, 4, {bezier:{values:[
			   {x:d1.x,y:d1.y},
			   {x:d2.x,y:d2.y},
			   {x:d3.x,y:d3.y},
			   {x:d4.x,y:d4.y},
			   {x:d5.x,y:d5.y},
			   ],
			   type:"thru",
			   curviness:0
			   },
			   ease:Linear.easeNone,
			   paused:true
			   });
			   
		public function motionguide() 
		{
			// constructor code
			draggerMc.buttonMode = true;   
			draggerMc.addEventListener(MouseEvent.MOUSE_DOWN, downHandler);
			draggerMc.addEventListener(MouseEvent.MOUSE_UP, upHandler);
		}
		
		public function downHandler(e:MouseEvent):void 
		{
		//an offset value that later lets us translate the mouse position to a progress() value
		startMouseX = mouseX - (draggerMc.x - (draggerMc.width/2));
		stage.addEventListener(MouseEvent.MOUSE_MOVE, update);
		stage.addEventListener(MouseEvent.MOUSE_UP, upHandler);
		}
		
		
		public function upHandler(e:MouseEvent):void 
		{
		stage.removeEventListener(MouseEvent.MOUSE_MOVE, update);
		stage.removeEventListener(MouseEvent.MOUSE_UP, upHandler);
		}
		
		
		public function update(e:Event):void 
		{
		//took some guesswork but it seems to do the trick
		tween.progress(Math.max((mouseX-startMouseX)/(d5.x-startMouseX), 0));
		}
	}
	
}

 

 

Share this post


Link to post
Share on other sites

Are you using GSAP v11 or v12? progress only became a function in v12 ( tween.progress(0); ); in v11 it is just a property ( tween.currentProgress = 0; ).

Edited by jamiejefferson
changed v11 .progress to .currentProgress
  • Like 1

Share this post


Link to post
Share on other sites

Are you using GSAP v11 or v12? progress only became a function in v12 ( tween.progress(0); ); in v11 it is just a property ( tween.progress = 0; ).

 

I thought i was but alas i wasn't.

 

Now when it compiles i get a Error #1009: Cannot access a property or method of a null object reference. referring to the coordinates for the Bezier

Share this post


Link to post
Share on other sites

Then I guess d1, d2, d3, d4, d5 aren't resolving? Have a look in Carl's zip and figure out what they are (I guess they might just be empty sprites placed at the bend points of the line, but I don't have Flash Pro to check).

Share this post


Link to post
Share on other sites

Yes, d1, d2, d3 are just those red dots (Movie Clips) that I dragged onto the stage to simplify the process of gathering the coordinates along the path.

Share this post


Link to post
Share on other sites

Hi Carl,

 

I dont know what i'm doing wrong with this so I've attached my files and maybe you can help?

 

Thanks

 

 

motion guide.zip

Share this post


Link to post
Share on other sites

You want to create your Bezier tween inside the class constructor. Paste this code into you class: 

 

 

 

package  
{
import flash.display.MovieClip;
import com.greensock.*;
import com.greensock.easing.*;
import com.greensock.plugins.*;
import flash.events.Event;
import flash.events.MouseEvent;




TweenPlugin.activate([bezierPlugin]);


public class motionguide extends MovieClip 
{
public var startMouseX;


//declare tween
public var tween:TweenMax;
  
public function motionguide() 
{
// constructor code


//move tween instantiation into constructor method
tween = TweenMax.to(draggerMc, 4, {bezier:{values:[
  {x:d1.x,y:d1.y},
  {x:d2.x,y:d2.y},
  {x:d3.x,y:d3.y},
  {x:d4.x,y:d4.y},
  {x:d5.x,y:d5.y},
  
  ],
  type:"thru",
  curviness:0
  },
  ease:Linear.easeNone,
  paused:true
  });


draggerMc.buttonMode = true;   
draggerMc.addEventListener(MouseEvent.MOUSE_DOWN, downHandler);
draggerMc.addEventListener(MouseEvent.MOUSE_UP, upHandler);
}


public function downHandler(e:MouseEvent):void 
{
//an offset value that later lets us translate the mouse position to a progress() value
startMouseX = mouseX - (draggerMc.x - (draggerMc.width/2));
stage.addEventListener(MouseEvent.MOUSE_MOVE, update);
stage.addEventListener(MouseEvent.MOUSE_UP, upHandler);
}




public function upHandler(e:MouseEvent):void 
{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, update);
stage.removeEventListener(MouseEvent.MOUSE_UP, upHandler);
}




public function update(e:Event):void 
{
//took some guesswork but it seems to do the trick
tween.progress(Math.max((mouseX-startMouseX)/(d5.x-startMouseX), 0));
}
}


}
 

That should do it.

 

Share this post


Link to post
Share on other sites

Thanks Carl, you rock, totally worked

Share this post


Link to post
Share on other sites

If i wanted this code to work where the button i am dragging from the right of the screen to the left, how would the code change?

 

Everything i do still makes the button move from the left side of the screen

Share this post


Link to post
Share on other sites

Please see the other thread you have related to this topic.

Share this post


Link to post
Share on other sites

Hi guys,

 

So if I have to stick with v11, how should I modify this line?

 

 tween.progress(Math.max((mouseX-startMouseX)/(d5.x-startMouseX), 0));

 

I tried 

 

tween.progress = Math.max((mouseX-startMouseX)/(d5.x-startMouseX), 0);

 

and it is not working (undefined property), wondering if anyone have thought on that, thanks in advance.

 

 

Regards,

 

Coty

Share this post


Link to post
Share on other sites

Try tween.currentProgress =

Share this post


Link to post
Share on other sites

Hi Carl,

 

Thanks for your input!

 

 

Best,

Coty

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×