12th Aug 2008

Cycling Fading Clips Using Tweens

I did this to answer a post on Flashkit and just to have something to play with. You can see the original post here. The indidividual wanted to have 3 clips fade in and out in sequence and have that sequence rotate. Here is what I came up with:

import fl.transitions.Tween;
import fl.transitions.TweenEvent;
import fl.transitions.easing.*;
/*
Create tween objects and immediately stop them so that they can be re-used.
*/
var yellowTween:Tween = new Tween (circle_mc.yellow_mc, “alpha”, None.easeInOut, 0 , 1 , 2 , true );
yellowTween.stop();
var blueTween:Tween = new Tween (circle_mc.blue_mc, “alpha”, None.easeInOut, 0 , 1 , 2 , true );
blueTween.stop();
var redTween:Tween = new Tween (circle_mc.red_mc, “alpha”, None.easeInOut, 0 , 1 , 2 , true);
redTween.stop();
/*Add an event listener to the first tween to trigger the fade in the oposite
direction. Subsequent listeners will be assigned and removed in the event
handler functions.
*/
yellowTween.addEventListener(TweenEvent.MOTION_FINISH, fadeOut);
/*
Since movie clips allow for the creation of dynamic properties (aka variables), simply create a
refence to the next tween that should be triggered directly on the clip. With
this system you could easily add aditional clips by cretaing a new tween and adding
another reference on the new clip to be tweened.
*/
circle_mc.yellow_mc.nextTween = blueTween;
circle_mc.blue_mc.nextTween = redTween;
circle_mc.red_mc.nextTween = yellowTween;
/*
Start the first tween to kick off the sequence. This should be the tween that you
added the event listener to in the previous code.
*/
yellowTween.start();

/*
Create a generic handler for the end of the fade in event. Since the TweenEvent object
holds a reference to the tween that caused the even, we can reference that tween via
the event.target property.
*/
function fadeOut(event:TweenEvent) {
/*remove the event listener that triggers this function from the tween since we have
gotten past the point of needed it and we dont want it to complete with the next part
of the sequence.
*/
event.target.removeEventListener(TweenEvent.MOTION_FINISH, fadeOut);
/*Add a new event listener that will trigger the next part of the sequence*/
event.target.addEventListener(TweenEvent.MOTION_FINISH, startNext);
/*Set the begin and finish properties of the tween object to the oposites
of those we used to create the fade in effect. I had originally tried to do
this with the built in yoyo function, but it produced un expected results.
*/
event.target.begin = 1;
event.target.finish = 0;
/*Restart the tween with the new properties, when this tween is finished,
it will trigger the new event handler we assigned in this function and
continue the sequence.
*/
event.target.start();
}
/*Now that the tween has fadded in and out, start the next tween. Again since TweenEvent
holds a reference to the tween that triggered the event, we can reference that tween.
Additionally, since the tween object holds a reference to the clip being tweened,
we can reference the properties of that clip. In this case we are interested in the
nextTween property we assigned in the previous code as this is what we will use
to start the next tween.
*/
function startNext(event:TweenEvent) {
/*Removed the event listener that triggered this function.*/
event.target.removeEventListener(TweenEvent.MOTION_FINISH, startNext);
/*
event.target is the tween that tirggred the function. obj is the property on
the tween objetc that holds a reference to the clip being tweened. hence, we can
reference the next tween to be triggered by accessing the nextTween property we created.
*/
/*
add a listener to trigger the fade out function completing the logical loop.
*/
event.target.obj.nextTween.addEventListener(TweenEvent.MOTION_FINISH, fadeOut);
/*Reset the values of the tween so that the effect is to fade in.*/
event.target.obj.nextTween.begin = 0;
event.target.obj.nextTween.finish = 1;
/*start the tween and the cycle repeate itself.*/
event.target.obj.nextTween.start();
}

After some playing with it, I was able to get it down to this:

import fl.transitions.Tween;
import fl.transitions.TweenEvent;
import fl.transitions.easing.*;
var yellowTween:Tween = new Tween (pics_mc.yellow_mc, “alpha”, None.easeInOut, 0 , 1 , 2 , true );
yellowTween.stop();
yellowTween.addEventListener(TweenEvent.MOTION_FINISH,fadeOut);

if (pics_mc.numChildren > 1) {
for (var c:int = pics_mc.numChildren-1; c>=0; c–) {
var clip:Object = pics_mc.getChildAt(c);
clip.alpha = 0;
if (c > 0) {
clip.nextClip = pics_mc.getChildAt(c-1);
} else {
clip.nextClip = pics_mc.getChildAt(pics_mc.numChildren-1);
}
trace (pics_mc.getChildAt(c).name)
trace (clip.nextClip.name)
}
}

yellowTween.start();

function fadeOut(event:TweenEvent) {
event.target.removeEventListener(TweenEvent.MOTION_FINISH, fadeOut);
event.target.addEventListener(TweenEvent.MOTION_FINISH, startNext);
event.target.begin = 1;
event.target.finish = 0;
event.target.start();
}
function startNext(event:TweenEvent) {
event.target.removeEventListener(TweenEvent.MOTION_FINISH, startNext);
event.target.addEventListener(TweenEvent.MOTION_FINISH, fadeOut);
event.target.obj = event.target.obj.nextClip;
event.target.begin = 0;
event.target.finish = 1;
event.target.start();
}

As long as all of the transitions are to be of the same length this works fine and all you would have to do to continue this would be to add additional clips to the housing clip (pics_mc) and the transition would be applied for you.

Posted by Posted by Jeremy Wischusen under Filed under ActionScript 3 Comments No Comments »

08th Aug 2008

An Eventful Revision

I finally got some time to play with my AnimatedClip class. I had a few ideas I wanted to try out. While playing with it, I realized that there was no real way to respond to tween events as all of the tweens resided in private instance variables. So I went back and added getter methods for the tween that I though people might like to respond to. So now you can do something like this:

//ball has com.vfd.animation.AnimatedClip linked to it via the library linkage.

import fl.transitions.easing.*;
import fl.transitions.TweenEvent;
ball.easing= Bounce.easeInOut;
ball.sizeTo(300,300,5);
ball.widthTween.addEventListener(TweenEvent.MOTION_FINISH, motionFinished);
function motionFinished(evt:TweenEvent) {
ball.widthTween.yoyo();
ball.heightTween.yoyo();
}

Will add this into the repository when I get home. I am mostly working on the AS3 version at this point.

Posted by Posted by Jeremy Wischusen under Filed under ActionScript 3, Open Source Projects Comments No Comments »

08th Aug 2008

Word Completion in Eclipse

For a long time I used IDEs such as SEPY and Flashdevelop, however, when I work on my MAC or Linux systems, I do not have these available to me and I have yet to find a full satisfactory replacement. One of the features I love about those editors is that when I define  a variable in a file, it then becomes available in the auto-completion feature. This was great as I did not have to constantly type out all of the variables and methods I defined.

The other day I was doing some research on Eclipse for an article I am writing and discovered that Eclipse has a word completion feature. If you start typing something and then press Alt+/ Eclipse will present you with an auto-complete box with all the words that start with what you have type, or if there is only one match, it will insert it.

While this is not quite as nice as the features in SEPY and Flashdevelop, it is definitely a time saver. Additionally, since this is an Eclipse feature, it works with all sorts of file types.

Definitely a feature worth knowing about.

Posted by Posted by Jeremy Wischusen under Filed under Eclipse Comments No Comments »

08th Aug 2008

Enforcing a Singleton

Been doing some research on Cairngorm and in the process came across this little trick for enforcing singletons. ActionScript will not let you set the access modifier for a constructor to private and as such, despite having a singelton architecture, there would be nothing stopping someone from directly calling new Singleton, which defeat the purpose of a singleton in the first place. The solution involves using what amounts to a private class that is a required argument of the constructor. This looks like this:

package
{

/**
* …
* @author Jeremy Wischusen <cortex@visualflowdesigns.com>
*/
public class Singleton
{
private static var instance:Singleton;
public function Singleton(enforcer:SingletonEnforcer)
{

}
public static function getInstance():Singleton
{
if (Singleton.instance == null)
{
Singleton.instance = new Singleton(new SingletonEnforcer);
}
return Singleton.instance;

}
}

}
class SingletonEnforcer
{}

Notice the class definition for SingletonEnforcer is ourside of the package definition. When you define a class like this in the same file as a another class, it is only available to main class defined in the file (the one inside the package statement).  In other words the class is private. Since the constructor requires an instance of this class, trying to instantiate using new Singleton will throw an error since there is no way that an enforcer can be created and passed to the constructor other than within the Singleton class itself.

Hopefully in future versions of ActionScript we will have private constructors (along with method overloading just in case anyone is listening hint hint), but for now, this should do the trick.

Posted by Posted by Jeremy Wischusen under Filed under ActionScript 3, OOP Comments No Comments »

30th Jul 2008

Can I Ganymede your Ubuntu?

So I decided to boot up the old Ubuntu box. I have been using Eclipse 3.4 (aka Ganymede) at work now for a week or so and decided to see if I could upgrade the old 3.2 version that came with Ubuntu. So fired up synaptics and low and behold all it had was the 3.2 version.

So I decided to go with a manual install. I did a quick search for Eclipse Ganymede Ubuntu and found this blog post. I followed the instructions there and had Ganny on my Ubuntu in no time.

Posted by Posted by Jeremy Wischusen under Filed under General Comments No Comments »

18th Jul 2008

A Little House Keeping

I am currently in the process of restructuring my site, so you may see some broken links and missing media, but I hope to have everything up and running in a few days.

Posted by Posted by Jeremy Wischusen under Filed under General Comments No Comments »

10th Jul 2008

A Cup of Joe

So I recently switch jobs and the new place I am working for uses JSP. So there may be some change of focus on some of my posts (when I get the time to do them).

Posted by Posted by Jeremy Wischusen under Filed under General Comments 1 Comment »

29th Jun 2008

Upon Reflection

The other day I was revising the one of the systems on one of the sites I work on into an object oriented structure. Everything was all well and good until I realized that I had to pass the values contained in one of my new objects into the templating system that we use. So I initially just passed a reference to the object. This did not work out so well.

It turns out that the templating system was having a hard time dealing with instance variables that are references to other objects and decided to throw a fit and halt processing. So I started looking for an easy way to translate my object into something the templating system could use (an array). More specifically, I wanted to produce an array that contained the values of my instance variables, but only the ones that were not references to other objects.

I decided to add a method called toArray to the object in question. Now I just needed an implementation. My first shot at this was to use PHP’s get_object_vars passing $this as a parameter.

public function toArray(){
return get_object_vars($this);
}

However, all was not well. It seems that when you call this function passing $this as a parameter it returned all of the variables from all of the objects referenced in instance variables. So I was basically back were I started.

So I gave it a bit of thought and came up with this.

/**

* Convert values held in instance variables into an array.
* This allows the data to be more easily used by a
* smarty variable  as well as making the data more easily cachable.
*
* @return Array
*/
public function toArray ()
{
$data = array();
foreach ( $this as $key => $var )
{
/**
* Exclude complex objects from the array.
*/
if ( !get_class( $var ) )
{
$data[$key] = $var;
}
}
return $data;
}

Problem solved. Now I only got back an array that contained the values of instance variables for that specific class that were not references to other objects.

Posted by Posted by Jeremy Wischusen under Filed under OOP, PHP Comments No Comments »

03rd Jun 2008

PHP http_build_query

I was browsing through
PHP Cookbook : Solutions and Examples for PHP Programmers by David Sklar, Adam Trachtenberg the other day and while looking through the section on making REST calls, i noticed this function:

http_build_query

I have been doing PHP for some time and this was the first time I had ever seen it. I asked one of my co-workers this morning about it and he had never heard of it either. Here is what it does:

string http_build_query ( array $formdata [, string $numeric_prefix [, string $arg_separator ]] )

Generates a URL-encoded query string from the associative (or indexed) array provided.

So in other words, instead of manually building a query string like:

$url = ‘http://www.somedomain.com/somepage.php?firstname=’.$firstName.’&lastname=’.$lastname;

You can do something like this:

$queryString = http_build_query(array(’firstname’=>$firstname, ‘lastname’=>$lastName));
$url = ‘http://www.somedomain.com/somepage.php?’.$queryString;

This could be especially useful for long query strings so you don’t have to type out all of the string concatenation. It you would like to learn more about this method go here.

Posted by Posted by Jeremy Wischusen under Filed under PHP Comments No Comments »

30th May 2008

YouTube API Video Upload

For my latest project I had to work with the new YouTube API. Let us just say the documentation could be improved. It is not that the information is not there, but there is a lack of cross referencing and if you jump to a particular sample, there seems to be the assumption that you have read other parts of the documentation and sometimes they refer to relevant sections, sometimes they do not. And some things are just left out entirely.

For example, the PHP API documentation shows you how to generate the file browse form, but does not mention (aside from a comment in the code about white space in the keywords) the restrictions on the inputs for the form that you would have to submit prior to getting to this point. Some of these include:

  • The < and > characters will cause an error if included in any of the inputs.
  • Submitting a single character keyword will cause an error.
  • The category select form items must have certain values, you can not simply submit the actual text representation of the category.
  • Description is limited to 5000 characters.
  • Total keyword string length can not exceed 120 characters and a single key word can not be over 25 characters.

These can be found elsewhere in the documentation, but again a link to relevant information in the actual PHP example could have saved me a lot of searching and time.

That being said, we did finally get it working (I think).

Posted by Posted by Jeremy Wischusen under Filed under PHP Comments No Comments »