Jump to content
Search Community

drag an MC along a motion guide line

Ulb test
Moderator Tag

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

Link to comment
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

Link to comment
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));
		}
	}
	
}

 

 

Link to comment
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

Link to comment
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.

 
Link to comment
Share on other sites

  • 2 weeks later...

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

Link to comment
Share on other sites

  • 1 year later...

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

Link to comment
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.
×
×
  • Create New...