Alex Uhlmann: Effects Archives

January 22, 2009

Download Flight Effect

Imagine an airplane that takes off the ground, flies across a distance and lands at an arbitrary destination. This post will explain how to do the same in Flex, using the Flight effect, which you can download here.

Before I explain any further, take a look at a running example. I’ve taken the Cairngormstore and added the Flight effect to the point when the user wants to add a product to his shopping cart. Simply click on the “Add to Cart” button to see the effect playing.

store_with_flighteffect.JPG

The key here is that the product doesn’t immediately appear in the shopping cart DataGrid control as the user presses the “Add to Cart” button. Instead, the Flight effect animates the product into the shopping cart control. Download it here.

The implementation of this effect is surly too exaggerated for any real life application and I strongly recommend consulting your User Experience experts before using an effect such as this. However, if applied responsibly, animating visual state changes of your applications instead of just setting and using movement to manage the user’s attention can help with cognition. Consult people who understand user experience design before using effects like this.

What is it?

The flight effect moves a display object either along a straight line or a quadratic bezier curve. While playing the display object is being scaled up and down to mimic a flight object taking off and landing (with using a good bit of imagination)

I’ll explain the usage of this effect with a simpler example. This flight effect is a standard Flex effect, so you can use it in ActionScript, Behaviours, Transitions etc. The following example shows a login panel moving and rotating to the bottom right corner of the screen. It plays in a Canvas container and all we need to set up the effect is to apply a simple Transition tag to the view state change.


<mx:states>
<mx:State name="stateA">
<mx:SetProperty target="{ login1 }" name="x" value="519"/>
<mx:SetProperty target="{ login1 }" name="y" value="323"/>
</mx:State>
</mx:states>

<mx:transitions>
<mx:Transition effect="{ mover }" />
</mx:transitions>

<mx:Sequence id="mover">
<mxeffects:Flight
target="{ login1 }"
duration="2000"
maximumHeight="2"
rotate="true" />
</mx:Sequence>

<sides:Login
id="login1"
change="currentState = ( currentState == 'stateA' ) ? '' : 'stateA';"/>

BTW: Behind the scences, Flight uses a MoveOnQuadCurve effect that I ported from AnimationPackage. You could also use this effect without Flight if you wish.

Flying across Flex container constraints

Since we use a Canvas container in the example above, the Panel component can be moved to arbitrary positions within that Canvas container. However, in some applications, like in the Cairngormstore sample application, we need to move across different containers. How I did this in Cairngormstore and how you can do the same in your applications will be the topic of the next section.

Flight Effect Applied

As pointed out in the end of the last section, the effect by itself isn’t enough if you want display objects to move across Flex containers. This section will show how I achieved this in the Cairngormstore sample application and how you can apply the same concept to your application. You can by the way also use a simple Move effect using the same concept.

But before I start with any implementation, let me please remind you on using this effect responsibly. As with many effects, applied in the wrong way, effects can dramatically reduce the user experience instead if increasing it. Consult a User Experience expert before you apply it to your application.

10000 feet overview

In order to let the flight object (our airplane) cross Flex container boundaries we need professional assistance. A FlightCaptain object can help us with

  • starting up our airplane.
  • finding our origin and destination coordinates.
  • flying the airplane according to a specified route.

If this sounds all a bit strange to you, follow me with a little example.

Let’s fly one box from the black area to the red area.

With clicking the button, the user tells the FlightCaptain to get going:

            var captain : FlightCaptain = new FlightCaptain();            
            captain.airplaneType = Login;         
            captain.origin = login;
            captain.destination = destinationContainer;
            captain.play();

We tell him the type of plane we would like him to use (a custom Panel component of type Login), and the start and destination locations.

In the above example the FlightCaptain creates a new airplane of type Login, flies it to the destination location and once landed, he removes it (he would put it back into the hanger)

But in your specific application, you might want the FlightCaptain to move not just copy the display object that we tell him is the airplane.

We can do that with removing the display object specified with the origin property when FlightCaptain is taking off…

  captain.addEventListener( TweenEvent.TWEEN_START, acualTakeOffTime );

…and adding it to the display list once the captain lands.

  captain.addEventListener( TweenEvent.TWEEN_START, acualTakeOffTime );

Important to note here is that we use the TweenEvent.TWEEN_START event. This event is triggered when the first tween update is performed, meaning we are sure our airplane is in the air (popup is created) and we can safely remove our old display object.

We also have access to the route our FlightCaptain is taking. His route property is a Flight effect. We can i.e. tell him to take a long way round with modifying the xBetween and yBetween properties of route.

captain.flight.yBetween = 1000;

Here’s the full code:



<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:sides="view.sides.*"
layout="horizontal">

<mx:Script>
<![CDATA[
import mx.events.TweenEvent;
import mx.events.EffectEvent;
import mx.core.Container;
import view.sides.Login;
import com.adobe.ac.mxeffects.FlightCaptain;

private var originContainer : Container;
private var destinationContainer : Container;

private function fly() : void
{
destinationContainer = ( login.parent == blackBox ) ? redBox : blackBox;
originContainer = ( destinationContainer == blackBox ) ? redBox : blackBox;

var captain : FlightCaptain = new FlightCaptain();
captain.addEventListener( TweenEvent.TWEEN_START, acualTakeOffTime );
captain.addEventListener( TweenEvent.TWEEN_END, acualLandingTime );
captain.airplaneType = Login;
captain.origin = login;
captain.destination = destinationContainer;
captain.configureFlight();
captain.play();
}

private function acualTakeOffTime( event : TweenEvent ) : void
{
originContainer.removeChild( login );
}

private function acualLandingTime( event : TweenEvent ) : void
{
destinationContainer.addChild( login );
}
]]>
</mx:Script>
<mx:Canvas
id="blackBox"
backgroundColor="black"
width="400" height="400"
>
<sides:Login
id="login" left="8" top="8"
change="fly()" />
</mx:Canvas>

<mx:Canvas
id="redBox"
backgroundColor="red"
width="400" height="400"/>

</mx:Application>



Behind the captain’s curtain

How does the FlightCaptain do his job? This section explains how you he manages to fly across Flex containers.

Let’s first take a look into FlightCaptain’s play method.

At first we get the airplane of the specified type…

airplane = getPlaneFromHanger();

…which simply creates a popup using PopUpManager.

private function getPlaneFromHanger() : IFlexDisplayObject
{
return PopUpManager.createPopUp( DisplayObject( Application.application ), typeOfPlane );
}

Then he finds out about the actual coordinates where he is expected to start and land.

var originCoords : Point = findOriginCoords( origin );		
var destinationCoords : Point = findDestinationCoords( destination );         

This translates the local coordinates of our specified origin and destination display objects into a global coordinate system. We need to do this because our origin and destination display objects are potentially deeply nested somewhere between various Flex containers. Our FlightCaptain prefers to fly high up in the sky (in popup coordinate space, which understands global coordinates), therefore we need to translate.

private function findOriginCoords( origin : DisplayObject ) : Point
{
		var originTopLeft : Point = new Point( 0, 0 );
		originTopLeft = origin.localToGlobal( originTopLeft );
		return originTopLeft;
}
		
private function findDestinationCoords( destination : DisplayObject ) : Point
{
	var destinationTopLeft : Point = new Point( 0, 0 );
	destinationTopLeft = destination.localToGlobal( destinationTopLeft );
	return destinationTopLeft;
}

Have fun with it!

Posted by auhlmann at 07:54 PM | Comments (0)

Lighted Distortion Effects and Tour de Flex

There’s a slightly updated version of the distortion effects shipping with the amazing Tour de Flex AIR application (flex.org/tour). This update adds another feature that our User Experience team found “adding to reality”. Lighting!

Lighting works on all effects supplied. Here’s how it looks like on CubeRotate:

lightingcube1.gif

But see all the effects in action from this example. Download it here directly.

The above version is still Flash Player 9 and Flex, 2, 3 compatible. If you can target Flash Player 10, make sure you check out the new 3D functionality, which makes effects such as these easier to do and more efficient.

Also, Tink has released a new Flex effects library (efflex.org) that also adds distortion effects. I’d definitely recommend checking out Tink’s work or even considering participating in this new exciting open source project. Great work Tink!


Here is How You Can Use it:

Generally you define a lighting source. When your lighting source is located on the top left then the effects will turn brighter once your display object turns towards the top or left.

To do that you just have to set two properties

  • -horizontalLightingLocation takes either a LEFT and RIGHT value (use DistortionConstants for setting this or FlexBuilder’s code hints).
  • -verticalLightingLocation takes either TOP or BOTTOM.
  • -lightingStrength is an optional property, which defaults to 7.5 if not set.

Lighting is turned off by default. To activate it you just need to set either the horizontalLightingLocation, verticalLightingLocation or both properties.

Posted by auhlmann at 07:36 PM | Comments (0)

March 05, 2007

Distortion Effects - Updated

Here’s a new version of the distortion effects.

Thanks for all your tremendous feedback on the previously released distortion effects. Some of that feedback is now included in this updated version. This version adds various features and updates. Here’s an excerpt:

Exceed Bounds

Much of the feedback I’ve received was about making the flip effect more realistic. The hint was to let its bounds overlap while the flip effect is coming towards the user. (flipping in). The new exceedBounds property on the Flip effect does exactly that and is now turned on by default!

exceedBounds.gif


Pop mode UP

The Pop effect now has an additional mode. The default mode is DOWN, which pops a display object off a stack/pile, away from the user. The new UP mode pops it towards the user.

popDown.gif

Scaling Support

Some of you have experienced issues with distortions done on display objects that are below other display objects, which are being scaled. You can scale display objects either using UIComponent’s or DisplayObject’s scaleX, scaleY properties or with modifying the DisplayObject’s transform matrix (a and d properties). This version of the distortion effects supports any scalings applied to any parent display objects in your display list.


Support of More Environments

My goal with these effects always was to support all possible environments where you can use these effects and distortions. With environments I meant i.e. using distortions or utilities in a non Flex framework environment, using only the Flash Player API. But also the use in different Flex framework containers and effect setups, i.e. States and Transitions, hideEffects, ActionScript effects, with ViewStacks, custom containers etc.

This version increases the number of environments to support to the point that I currently haven’t heard of an environment that isn’t supported. If you have one, let me know and feel free to send me an isolated example and I’ll try to help out.

This version added support for some States and Transition usages i.e. with supporting multiple siblings and improves error handling in case views cannot be initialized.

See them in action here.

Download here!

Posted by auhlmann at 12:37 AM | Comments (160)

November 03, 2006

Download Distortion Effects – From MAX 2006

For everyone who couldn’t attend my MAX presentation in Las Vegas, here is the presentation as PDF. Furthermore, I’ve released the complete source code for every effect shown.

And here is the Flex 2.0.1 version.

Behind the scenes, these effects are using the DistortImage utility from the open source 3D Engine Sandy. Make sure you check out Sandy if you haven’t yet! The effects included are called Flip, CubeRotate, Push, Pop, Door and Gate. But instead of talking about them, just see them in action for yourself:

Distortion Effects

This sample application lets you play with all effects available. You can also see different configurations, i.e. try enabling the blur checkbox.

FlipCubeBlur1.png

With the source code, you can use all the showcased effects in your own applications. They tie into the existing Flex 2 Effects Framework infrastructure, meaning you can use them in ActionScript, Transitions, hideEffect properties etc...like any other Flex 2 Effect. Here is one simple example on how it looks like using a hideEffect:

<?xml version="1.0" encoding="utf-8"?>
<mx:VBox 
	xmlns:mx="http://www.adobe.com/2006/mxml" 
	xmlns:sides="view.sides.*"
	xmlns:mxeffects="com.adobe.ac.mxeffects.*">
        
	<mxeffects:CubeRotate 
		id="flipIn" 
		target="{ login }" siblings="{ [ registration ] }" 
		direction="RIGHT" duration="1000"/>
	<mxeffects:CubeRotate 
		id="flipBack" 
		target="{ registration }" siblings="{ [ login ] }" 
		direction="LEFT" duration="1000"/>
        
	<mx:ViewStack id="loginViewStack">
        
		<sides:Login 
			id="login" 
			title="Login" 
			hideEffect="{ flipIn }" 
			change="loginViewStack.selectedChild = registration;"/>
		<sides:Registration 
			id="registration" 
			title="Registration" 			
			hideEffect="{ flipBack }" 
			change="loginViewStack.selectedChild = login;"/>
	
	</mx:ViewStack>
	
</mx:VBox>

And here is how it looks like using States and Transitions:

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas 
	xmlns:mx="http://www.adobe.com/2006/mxml" 
	xmlns:sides="view.sides.*" 
	xmlns:mxeffects="com.adobe.ac.mxeffects.*">
	
	<mx:states>
		<mx:State name="registrationState">
			<mx:RemoveChild target="{ login }"/>
			<mx:AddChild>
				<sides:Registration 
					id="registration" title="Registration" 
					change="currentState = ''" />
			</mx:AddChild>
		</mx:State>
	</mx:states>
	
	<mx:transitions>
		<mx:Transition fromState="" toState="registrationState" 
			effect="{ flipFront }"/>
		<mx:Transition fromState="registrationState" toState="" 
			effect="{ flipBack }"/>
	</mx:transitions>
	
	<mx:Sequence id="flipFront">		
		
		<mxeffects:CubeRotate 
			target="{ login }" siblings="{ [ registration ] }" 
			direction="RIGHT"/>
		
		<mx:RemoveChildAction target="{ login }"/>
		<mx:AddChildAction target="{ registration }"/>				
	</mx:Sequence>
	
	<mx:Sequence id="flipBack">		
	
		<mxeffects:CubeRotate 
			target="{ registration }" siblings="{ [ login ] }" 
			direction="LEFT"/>
			
		<mx:RemoveChildAction target="{ registration }"/>
		<mx:AddChildAction target="{ login }"/>				
	</mx:Sequence>
	
	<sides:Login id="login" title="Login" 
		change="currentState = 'registrationState';"/>
	
</mx:Canvas>

You can also create your own customized Flex Framework Effects using base and utility classes of the distortion effects. Make sure you check out the chapter 15 of Creating and Extending Flex 2 Components (flex.org > Documentation) for more information on Flex Effects customizations.

Distortions

Independently of effects, you can also use the source code to create your own distortions using the com.adobe.ac.mxeffects.Distortion. The API can be very simple i.e. like:

var distortion : Distortion = new Distortion( login );
distortion.push( 50, DistortionConstants.TOP );

For more customized distortions you can use the distortion explorer, which is also included in the download.

The Flex 2 Framework is free but still, you might not able to use it because you create extremely lightweight (filesize) content or/and developing with the Flash IDE (Flash Professional 9 ActionScript 3.0 Preview). Anyway, you can still make use of distortions with using com.adobe.ac.mxeffects.SimpleDistortion.

Determining Filter Bounds at Runtime

And independently of effects and distortions, you might want to use the com.adobe.ac.util.DisplayObjectBoundsUtil if you’re looking for how to determine the bounds (width and height) of a display object at runtime that might have filters applied. Check on SimpleDisplayObjectBoundsUtil if you can’t use the Flex framework.

For usage, just add the included DistortionEffects.swc into your project, check out the included sample applications and let me know how you get on with it!

UPDATED: I've published a blog entry to an updated version here. The source code and example links on this blog entry contain the updated version.

Posted by auhlmann at 01:08 AM | Comments (106)

September 08, 2006

MAX 2006: Leveraging Flex 2 and Flash Player 9 for Truly Cinematic Experiences

As MAX 2006 in Las Vegas is coming closer and it’s shaping up to be a fascinating conference. I’m talking about

Leveraging Flex 2 and Flash Player 9 for Truly Cinematic Experiences

and I’d like to give you more information where this will be about, in hope you consider joining my session!

I’ll talk about how cinematic effects can dramatically improve the user experience of a Rich Internet Application and can contribute significantly to the success of how your RIA will translate the experience that your costumer wants to deliver.

You will see new types of effects and learn best practices toward their use and creation.

New Flex Effects Leveraging Flex 2 Features

I’ll showcase a variety of different effects but most importantly I'll showcase a new type of cinematic effects, leveraging the performance improvements, the new bitmap manipulation features and the new Effects Framework in Flex 2. You'll be given ideas and complete source code for these new type of effects and will be able to create your own customized effects based on the principles demonstrated.

One of these effects is a flip effect. I’ve a little teaser for you here:

See the Flip effect

How this is done, how you can use it in your own work and how all the other effects look like…stay tuned for MAX 2006!

Future of AnimationPackage

Some of you might know that I’ve developed AnimationPackage, an ActionScript 2 library for Flash and Flex 1.x developers. I’ll outline how I see the future of this framework and how I see it fitting alongside the Flex 2 effects framework.

See you soon, on the
25. October, Wednesday, 1:45 p.m
and the
26. October, Thursday, 3:00 p.m.
in Las Vegas!

I'm excited!

Posted by auhlmann at 10:35 AM | Comments (6)