scrubbing video [NetStream]

I always like to do my video players from the ground up…i guess it’s just my style. I have used often the FLVPlayback, but there is a satisfaction in creating your own player. One thing that always plays with my head is the scrubbing. It’s the actual Math that gets me, and generally, i get it after a few tries…but never on the first (much like the custom scrollbar) . Read the rest of this entry »

Orbit in Papervision, the real way and the easy way

I have been working with papervision3D only a bit now, and really starting to get the concepts of the camera, 3D space, containers, prmitives, etc. The hardest part by all means has been knowing/learning when to manage the camera vs just the container object holding 3D objects. A hot tip (up for dispute) from one of our motion designers was to try not to move the camera and to rely on the container rotation. This is great, if the background is static and has no need to relay an orbiting effect. However, in my case, i needed the camera to swing around the object in question. Knowing that, my approach was to “fasten” the camera to a virutal boom. Essentially, this “boom” would be an empty DisplayObject3D that will spin. The camera would in turn respond to that rotation accordingly.

So, into Trigland we go. Like all Flash trig mind games, the only thing you will need is an angle and a radius. The rest was done thousands of years ago by the greeks using their good friends cosine and sine.

[NOTE: i have to give all the math credit to Tyler Egeto from a post at the DDBlog, here . Tyler, you don't know it, but thanks.]

 
//calling the method below from my render loop(enterFrame)
private function setCamera() : void
{
 
var rdx = boom.rotationX *(Math.PI/180);	//rotation in radians
var rdy = boom.rotationY *(Math.PI/180);	//rotation in radians
 
var radius = boom.distanceTo(cam);
 
/*---------------------------------------------------------------------->
//Egeto's original math follows the mouse movement. A very cool effect:
var theta = mouseX*0.02;
var phi = mouseY*0.02;
 
cam.x = radius * Math.cos(theta) * Math.sin(phi)
cam.z = radius * Math.sin(theta) * Math.sin(phi)
cam.y = radius * Math.cos(phi);
 
 
 
//however i want to follow the "boom", so i need to change up a few things in the formula
//(not the swap of sin and cos, as well as the cam.x swap with cam.y)
---------------------------------------------------------------------->*/
var theta = rdx
var phi = rdy
 
 
 
cam.y = radius * Math.sin(theta) * Math.cos(phi)
cam.z = radius * Math.cos(theta) * Math.cos(phi)
cam.x = radius * Math.sin(phi);
}
 
however, let it be known, the same guy who told me to resist moving the camera (and also knows very little about code), seemed to know enough to bring the orbit method into a useful purpose.
 
cam.orbit(90,boom.rotationY,true,boom);

ha!. Well, not all for nothing. Practicing the trig is hugely necessary and will no doubt pay off another day.

Letterize [random text letter effect]

letterize in action

letterize in action

i always liked the random letter effect, so i decided to give a go in AS3 and make a class of it. All you have to do is pass the text field…i have not tested it on an html text field…(hmmmmmm, looks like i just found the next version)-Anyway, it’s pretty straight forward… for the demo you can update the text to be whatever you type, adjust the speed, and play with random vs orderly. The orderly version was more straighforward than the unorderly… could probably be cleaner, but this will do.

source is here

sample is here

scrollbar math

This is something i have done lots, and can never remember how i did it. Worse, i think everytime i do this, it’s different…which is fine, but it would be nice to just type it out without having to think about it…or worse, go to the white board and draw it out. I will say right off that my scrolling textboxes seem to be more of a work around. I am not a fan of the scroll method, native to the TextField Object…i find them (for now) unintuitive. My resolution, and again, not great, is to make a text field, and throw over it, a dynamic mask.

Anyway, today’s dynamic scrolling challenge was achieved like so:

  1. add shell movie clip to hold everything
  2. add background (using bitmap/bitmapdata)
  3. add a text field
  4. add a mask to the text field (repurpose the bitmap object)
  5. add text to the text field
  6. add a custom scrollbar if the text field if the text field is greater than the mask height

i am not going into points 1-5…but i will talk now about the math i created the scrollbar, and how i calculate the math to shift the text box in relation the the dragger. For ease, this scroll bar will be only a dragger, locked to its x-axis. It will be 20×20, and ride on the far right of the shell mc:

Now, the code:

private static function addScrollBar():void
{
var d=dragger();
d.x=_container.width-(d.width)
_container.addEventListener(MouseEvent.MOUSE_DOWN,mousedown);
_container.addChild(d)
}
private static function dragger():MovieClip
{
var mc:MovieClip=new MovieClip()
mc.buttonMode=true;
_scroller=mc;
var g=mc.graphics;
g.beginFill(0xffffff);
g.drawRect(0,0,_draggerWidth,_draggerHeight)
g.endFill()
mc.alpha=.5
return mc;
}

that’s the dragger….plain simple graphics

/*-----------------------------------------------------
//MOUSE EVENTS
-----------------------------------------------------*/
private static function mousedown(e:MouseEvent):void
{
var d=_scroller;
_container.addEventListener(MouseEvent.MOUSE_MOVE,dragging);
_container.addEventListener(MouseEvent.MOUSE_UP,stopdrag);
_landing.addEventListener(MouseEvent.MOUSE_UP,stopdrag);
}
private static function stopdrag(e:MouseEvent):void
{
_container.removeEventListener(MouseEvent.MOUSE_MOVE,dragging);
}
private static function dragging(e:MouseEvent):void
{
var txHeight=_textbox.height;
var d_pos=(_scroller.y+_scroller.height);    //dragger posiion
var ratio=txHeight/_virtualHeight;
var sc=Math.floor((d_pos-20)*ratio)         //20 is from the dragger dimensions
_textbox.y=-(sc-91)
_scroller.y=_instance.mouseY;
 
}

Not so bad- the actual drag is based on a mouse move event handler….and now the math:

i am first getting the absolute height of the text box and all its contents= txHeight. This is the longest part in terms of height. I then look for the ratio of this very long instance vs the viewable portion from the mask (_virtualHeight). Once i have that raio, as i slide the dragger, i set a variable that takes that position and multiplies it by the ratio. That “-20″ you see  is the offset from the dragger height. Finally, i set the textbox’s y axis to that variable, and subtract 91. Why 91??? i have not idea…For some unexplanable reason, i had to explore for an offset. i turn that unknown to you guys…in fact, that’s the whole point of this post. As i’ve said, this etire site is dedicated to understanding code. It may be that my entire approach here is wrong…it seems to work, but lets tear this math apart and make it better. If you see a problem or have a better way, let me know

Trig rocks, but it ain’t easy

One thing that kills me is trig. I love it, but it’s nothing natural for me…some key forumlas i have commited to memory, but i have learned that almost every thing needs to know distance of the x-axis and y. so, before we get deep, let’s do that
[i will use 'this' to refrence the object needing this math]
//distance from x point and y point
var dx=xpoint.x-this.x
var dy=ypoint.y-this.y

After this, we can do lots….get cosine, sine, arctangent. Huh? Wha? yeah, you will need these things if you want to do some fun waves, circles, or just need some angles. To make things worse, most of the times we need radians, unless we are going to do some rotation. Using those two distance values:
var radians= Math.atan2(dy,dx)
cool, now, let’s use it all to make a simple disc that rotates according to where you press. I am not going to post the whole source, but here is the gist of the rotation using the mouse event handlers:

private function mousedown(e:Event):void
		{
			rotate=true
			var sx=stage.mouseX-this.x;
			var sy=stage.mouseY-this.y;
			var at=Math.atan2(sy,sx)
			initAng=(at*180/Math.PI)-this.rotation
 
			tm.start();
			stage.addEventListener(MouseEvent.MOUSE_UP,mouseup);
		}
 
		private function mouseup(e:Event):void
		{
			rotate=false;
			endRotation()
		}
		private function swing(e:TimerEvent):void
		{
			if(rotate)
			{
				var difx=stage.mouseX-this.x
				var dify=stage.mouseY-this.y;
				var atan=Math.atan2(dify,difx);
				var ang=atan*180/Math.PI;
				var tgA=(ang-this.rotation)*.2;
				this.rotation=ang-initAng;
			}
			e.updateAfterEvent()
		}
                private function endRotation()
		{
			stage.removeEventListener(MouseEvent.MOUSE_UP,mouseup);
			tm.stop()
		}

You probably saw something that was a bit of a twist:

var sx=stage.mouseX-this.x;
			var sy=stage.mouseY-this.y;
			var at=Math.atan2(sy,sx)
			initAng=(at*180/Math.PI)-this.rotation

You need this initAng to track the difference of where you are clicking to where the disc may have already been rotated. It’s an offset. Let’s say the disc is already rotated 32 degrees. That’s great and all, but without the offset, as soon as you click the disc, it will flip to your mouse pointer. With an offset like initAng , we can subtract the new click angle from previous rotations allowing for a smooth rotation, no matter where we click.