Jump to content
GreenSock

droyde

Animating with TweenLite bezier with line as guide

Recommended Posts

G'Day all!

This is a question for Jack or anyone here.

 

Does anyone know how to animate object with a drawn line on stage (or library) using the tweenlite's bezier? I mean I can draw points on the stage and position them exactly, but the track that's invisible is basically the one that's uncontrollable. What I really want to achieve is basically an animation that's based around the track and I really want to be able to control where exactly the object is going. Because with using bezier tool, I get this funny animation of swirling in loop and again this is understandable because of the nature of bezier.

 

So back to the question, has anyone done it with a drawn line on a stage and use tweenlite to basically use it as track? Is this possible? My understanding would be that we need to have an AS3 to understand or trace the line and redraw them in code so it sort of convert them to an array of X and Y and put it to the bezierThrough. Would be sweet if you can. Thanks in advance!

Link to comment
Share on other sites

Just adding new for that too. I really need this to be code based but using the stage line that is hand-drawn and in library but I don't want to use the timeline animation or timlinelite nor timelinemax as it increases performance for the stuffs that I'm doing (optimising for mobile). Thanks.

Link to comment
Share on other sites

Is anybody here? Jack?

 

Jack, I think you should include this guy's (http://wonderfl.net/c/hzfJ) math algorithm for a better motion guide and it's worth the investment for the way how your tolerance variable work. The less will have more of his effect which is more accurate and the bigger value it will have that elastic long curve. Because the problem with the standard curve of BezierPlugin is that it has real big tolerance to it so it doesn't really take the shortest direction but making a bigger curve then travel through the longer distance. Which is a big problem there.

 

Here's what I edited:

if (through) {
for (p in props) {
a = makeBezierArray (props[p]);
all[p] = b = [];
if (a.length > 3) {
	b[b.length] = [a[0], a[1], (a[1] + a[2]) / 2];
	for (i = 2; i < a.length - 2; i++) {
		b[b.length] = [b[i - 2][2], a[i], (a[i] + a[i + 1]) / 2];
	}
	b[b.length] = [b[b.length - 1][2], a[a.length - 2], a[a.length - 1]];
} else if (a.length == 3) {
	b[b.length] = [a[0], a[1], a[2]];
} else if (a.length == 2) {
	b[b.length] = [a[0], (a[0] + a[1]) / 2, a[1]];
}
}
}

 

Add this function below:

public static function makeBezierArray(p0:Array):Array {
// make a copy you can mess with 1st
var p:Array = p0.concat ();
// extrapolate in some way
if (p.length < 2) {
p.unshift (p [0]);
p.push (p [p.length -1]);
} else {
p.unshift (p [0] - 0.5 * (p [1] - p [0]));
p.push (p [p.length -1] - 0.5 * (p [p.length -2] - p [p.length -1]));
}

var bezier:Array = [];
// convert all points between p[0] and p[last]
for (var i:int = 1; i < p.length -2; i++)
{
var b1:Number = -p[i -1]/6 +p[i] +p[i +1]/6;
var b2:Number = +p[i]/6 +p[i +1] -p[i +2]/6;
bezier.push (b1); bezier.push (b2);
}
return bezier;
}

 

You need to somehow integrate this with a new variable. I don't know what your tolerance variable really for there. Hope that helps. But if you still have the answer for my previous question - which is how to integrate this bezier curve to a library or stage object, that would be fantastic if possible. Cheers.

Link to comment
Share on other sites

hello droyde,

 

Only Jack will be able to address the feasibility of integrating your suggestion. Thanks for providing the link and info, I found it interesting.

 

As per your main query about sucking the curve data out of a line/curve that is drawn in the flash IDE, I agree that would a great help for many development purposes beyond GS. I imagine if it were possible, some flash genius would have done it already. this is the closest I've seen, http://www.quasimondo.com/shapedecoder/ ... ecoder.php but yet not what you need.

 

------

 

something else that is not exactly a solution but possibly may be useful for something.

 

In Flash CS4+ you could create create a tween with a motion guide that you draw and by "copying motion as AS3" you can get all the points that are used like so:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

...

 

you could probably loop through all those points programmatically and have something that works pretty decent. just a thought.

 

Carl

Link to comment
Share on other sites

Thanks for the reply Carl. I really appreciate it. It seems so dry here ;) And also thanks for the info there - some useful stuff and might save me from redrawing my curves and all that are existing with that frame keyscript there. Cheers mate!

Link to comment
Share on other sites

no problem. I tried searching for something I saw awhile ago where some dude was using pixel bender to detect a path around text and then he used a particle-engine sparkler thing follow the path around the outline. I know its out there somewhere. the internet has gotten too big:)

Link to comment
Share on other sites

Yeah it's bombarded with whole lot of information. You spend hours and hours for research. Anyway, keep us posted. Have a great one mate!

Link to comment
Share on other sites

  • 2 years later...

Hi, I found kind of a solution. It only works if you draw in a simple direction to the right and down but not if you go back to the left or up (doesn't work if you draw a circle)
 

var myBitmapData:BitmapData = new BitmapData(500, 500)
myBitmapData.draw(new Path());
var myBitmap:Bitmap = new Bitmap(myBitmapData);

var throughPoints:Array = new Array();
var pathINDX:Number = 0;
var ballSpeed:Number = 30;
var firstPoint:Boolean = false;

var my_shape:Shape = new Shape();
addChild(my_shape);
my_shape.graphics.lineStyle(1, 0x66CCFF, 1);

function generatePath () 
{
	for (var xpath:Number = 0; xpath < myBitmapData.width; xpath++) 
	{
		for (var ypath:Number = 0; ypath < myBitmapData.height; ypath++) 
		{
			if (myBitmapData.getPixel32(xpath,ypath).toString(16) != "ffffffff" ) 
			{
				throughPoints.push([xpath, ypath]);
				
				if (!firstPoint) 
				{
					firstPoint = true;
					my_shape.graphics.moveTo(xpath, ypath); 
				}
				
				my_shape.graphics.lineTo(xpath, ypath);
			}
		}
	}
	
	my_shape.graphics.endFill();
}

function onFrame (e:Event):void 
{
	if (pathINDX<throughPoints.length-ballSpeed) 
	{
		pathINDX+=ballSpeed;
	
		ball_mc.x = throughPoints[pathINDX][0];
		ball_mc.y = throughPoints[pathINDX][1];
	}
}

addEventListener(Event.ENTER_FRAME, onFrame);
generatePath (); 

post-13801-0-34263000-1377197876_thumb.png

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.
×