I’ve just uploaded a new video tutorial (48 min) for my lightweight AS3 MVC Framework SomaCore.

You can now get started with it. I explain how to create the framework instance, how to create a wire, create views, create commands and how to intercept them.

SomaCore Getting Started Video Tutorial

I hope you like it!

  • Digg
  • del.icio.us
  • Facebook
  • email
  • Netvibes
  • RSS
  • Twitter
Vote in HexoSearch

Comments 1 Comment »

Here is how to bring life to an image using the filter DisplacementMapFilter.

Click here to see the demo.

I got the idea from a video made by Chad Perkins (thanks Chad, you're giving me a lot of inspiration!) where he is showing this effect in After Effects. My Flash nature pushed me to reproduced it with AS3. The result is great even if the After Effects version is slightly better, maybe the Flash version can be tweaked a bit more.

Here is how it works. I used this wonderful picture from my friend Ziemowit Maj :)

You also need a second picture that will describe the map of the filter using luminance. The foreground areas should be whiter than the background areas. I made this picture using Photoshop, the brush tools, and of course my proven drawing skills :D

I apply the DisplacementMapFilter on a BitmapData and I move the map position over time. It is not too complicated, but you can probably spend more time than me to draw the map correctly. Be careful not to make a distortion too big or it will look weird! Here is the code:

Actionscript:
  1. package {
  2.     import caurina.transitions.Tweener;
  3.  
  4.     import flash.display.Bitmap;
  5.     import flash.display.BitmapData;
  6.     import flash.display.BitmapDataChannel;
  7.     import flash.display.PixelSnapping;
  8.     import flash.display.Sprite;
  9.     import flash.display.StageAlign;
  10.     import flash.display.StageScaleMode;
  11.     import flash.events.Event;
  12.     import flash.filters.DisplacementMapFilter;
  13.     import flash.filters.DisplacementMapFilterMode;
  14.     import flash.geom.Point;
  15.     import flash.geom.Rectangle;
  16.  
  17.     /**
  18.      * <b>Author:</b> Romuald Quantin - <a href="http://www.soundstep.com/" target="_blank">www.soundstep.com</a><br />
  19.      * <b>Company:</b> Less Rain - <a href="http://www.lessrain.com/" target="_blank">www.lessrain.com</a><br />
  20.      * <b>Class version:</b> 1.0<br />
  21.      * <b>Actionscript version:</b> 3.0<br />
  22.      * <b>Copyright:</b>
  23.      * <br />
  24.      * <b>Date:</b> Aug 16, 2010<br />
  25.      * <b>Usage:</b>
  26.      * @example
  27.      * <listing version="3.0"></listing>
  28.      */
  29.    
  30.     public class Main extends Sprite {
  31.        
  32.         [Embed(source="../assets/photo.jpg")]
  33.         private var Photo:Class;
  34.         [Embed(source="../assets/map.jpg")]
  35.         private var Map:Class;
  36.        
  37.         private var _photo:Bitmap;
  38.         private var _map:Bitmap;
  39.         private var _point:Point;
  40.         private var _photoDisplaced:Bitmap;
  41.         private var _photoDisplacedData:BitmapData;
  42.         private var _filter:DisplacementMapFilter;
  43.        
  44.         private var _range:Number = 17;
  45.  
  46.         //------------------------------------
  47.         // private, protected properties
  48.         //------------------------------------
  49.        
  50.        
  51.  
  52.         //------------------------------------
  53.         // public properties
  54.         //------------------------------------
  55.        
  56.        
  57.        
  58.         //------------------------------------
  59.         // constructor
  60.         //------------------------------------
  61.        
  62.         public function Main() {
  63.             initialize();
  64.         }
  65.  
  66.         //
  67.         // PRIVATE, PROTECTED
  68.         //________________________________________________________________________________________________
  69.        
  70.         private function initialize():void {
  71.             // stage
  72.             stage.frameRate = 41;
  73.             stage.align = StageAlign.TOP_LEFT;
  74.             stage.scaleMode = StageScaleMode.NO_SCALE;
  75.             // photo
  76.             _photo = new Photo();
  77.             // photoDisplaced
  78.             _photoDisplacedData = new BitmapData(_photo.width, _photo.height);
  79.             _photoDisplaced = new Bitmap(_photoDisplacedData, PixelSnapping.AUTO, true);
  80.             _photoDisplaced.scaleX = 1.05;
  81.             _photoDisplaced.scaleY = 1.05;
  82.             _photoDisplaced.x = (stage.stageWidth - _photo.width)>> 1;
  83.             _photoDisplaced.y = (stage.stageHeight - _photo.height)>> 1;
  84.             addChild(_photoDisplaced);
  85.             // map
  86.             _map = new Map();
  87.             // point
  88.             _point = new Point(-(_range), 0);
  89.             // enterframe
  90.             addEventListener(Event.ENTER_FRAME, loop);
  91.             // scroll motion
  92.             move(_range);
  93.         }
  94.  
  95.         private function move(target:Number):void {
  96.             Tweener.addTween(_point, {time:2, x:target, transition:"linear", onComplete:move, onCompleteParams:[target*-1]});
  97.         }
  98.  
  99.         private function loop(event:Event):void {
  100.             _filter = new DisplacementMapFilter(
  101.                 _map.bitmapData,
  102.                 _point,
  103.                 BitmapDataChannel.RED,
  104.                 BitmapDataChannel.RED,
  105.                 _point.x,
  106.                 _point.y,
  107.                 DisplacementMapFilterMode.WRAP);
  108.             _photoDisplacedData.applyFilter(_photo.bitmapData, _photoDisplacedData.rect, new Point(0,0), _filter);
  109.             _photoDisplaced.bitmapData.draw(_photoDisplacedData, null, null, null, new Rectangle( _point.x, _point.y, _photo.width, _photo.height), true);
  110.         }
  111.        
  112.         // PUBLIC
  113.         //________________________________________________________________________________________________
  114.        
  115.        
  116.        
  117.     }
  118. }

  • Digg
  • del.icio.us
  • Facebook
  • email
  • Netvibes
  • RSS
  • Twitter
Vote in HexoSearch

Comments 3 Comments »

Let's start by a Flash demo here and a bit of explanation below.

While training myself to get better with After Effects, I stumble on a very interesting thing about color.

I was watching a Chad Perkins video about HDRI and color depth, more precisely, 32 bits rendering.

He showed what was happening with a Fast Blur effect (which is a 32 bits effect), and a white text in a 32 bits After Effects project.

Here is the rendering in a 8 bits project, just a normal blur.

And here is the result is you set the project to be 32 bits.

So what's happening here? We can see there is some kind of halo, or glow, but there's just a blur. I found the result pretty nice, a lot of luminance, and they call that "superwhite". I didn't find a lot of information, maybe there is another term for that. I found that very intriguing.

I've started to think how to get this effect in flash. The problem is Flash is only rendering 8 bits. I quote a details I found about Pixel Bender:

Although Pixel Bender images have 32-bits per channel, graphics in Flash Player and AIR only have 8-bits per channel. When a kernel is run, the input image data is converted to 32-bits per channel and then converted back to 8-bits per channel when kernel execution is complete.

But I wanted to have a try anyway and even if I don't have the exact same effect in Flash, I found out that something is happening. Here is what I've done.

1. I put a white text on the stage (2 actually for other tests)
2. I've added a Blur effect (15 and 15)

Here is the result, again just a normal blur.

Then I've changed the alpha multiplier value (ColorTransform property) from 1 to 2.5, nothing happened obviously, alpha 1 or 2.5 is the same isn't it? But here is the effect coming, if you add a bit of color, for example by setting the blue multiplier from 1 to 0.99, you then get a (fake?) superwhite. Here is the result:

Again, there's no glow of anything, it is just a color and alpha effect. The amount of "superwhite" is changed with the value of the alpha multiplier, at least from 1 to... 20 or something.

Pretty cool huh? It is a fake superwhite because if I trust After Effect, it can happen only with 32 bits rendering, and I also don't get exactly the same result as in After Effect, the color halo around is missing. But still, I found that quite intriguing. I'm not that good with colors, but I believe that what's happening is the alpha channel that is multiplied by each color channel. Maybe someone will have a more in-depth explanation of what's happening? I would be curious.

To check out the demo, click here.

You can click the button at the bottom to applied values. You can see the difference between the "Normal Blur" and the "Super White".

  • Digg
  • del.icio.us
  • Facebook
  • email
  • Netvibes
  • RSS
  • Twitter
Vote in HexoSearch

Comments 2 Comments »

Finally, BaseUI version 4 is released!

If you don't know what is BaseUI, it is a lightweight layout manager written in pure AS3 that is helping you to handle the position and size of your elements in a Flash layout (a site, an application and or whatever you can build with AS3).

More specifically, it is calculating positions and size when you resize your browser to update your elements. BaseUI makes you able to use layout properties (such as top, bottom, horizontalCenter, and so on) on any DisplayObject instance, much like you would do in a Flex environment.

You can use BaseUI with a single DisplayOBject instance, with tons of DisplayObject instances or in a more complex system with layout classes (such as canvas, horizontal and vertical box, and tile).

Before showing you how it works with some simple examples, I'd like to mention that BaseUI has been completely rebuilt from scratch. I did that because I wasn't happy at all with a lot of things in the previous version. I wanted a very clean and effective library, with no hacks to make things works, which would make it very reliable.

The library is now contained in a com.soma.ui package, it will be part of the next Soma MVC Framework version.

I removed two things from the previous version:

- the width and height ElementUI properties, as it wasn't making sense, you can now just set the width and height on your own DisplayObject instances.
- the percentage values for width and height, that is not possible anymore, I might add specific properties in the future if requested

Enough talk, you will get everything you need on the BaseUI page:

demo

source

documentation

Concept and the need of a reference

The important concept to understand is that you need to specify a reference to a BaseUI instance, or to the class that will handle the DisplayObject (which is the ElementUI class). A reference is what will be used to calculate size and position. For example, if you want your DisplayObject to be at 10 pixels from the bottom, you need to tell the library from what object. That's what a reference is.

The reference can be any DisplayObjectContainer, such as the stage, a sprite, a layout, etc. Once you understand completely the need of having a reference, it is good to know that is doesn't have to be a parent of your DisplayObject, it can be anything, anywhere. The only important things is that the reference must have a proper width and height, the stage or a layout class will always have it, but an empty Sprite instance won't, the values will be 0.

All the following example will use the stage as a reference, but again, you can use anything you want.

Create a BaseUI instance

Actionscript:
  1. var baseUI:BaseUI = new BaseUI(stage);

Adding and removing DisplayObject instances

Actionscript:
  1. var baseUI:BaseUI = new BaseUI(stage);
  2. var mySprite:Sprite = new Sprite();
  3. var element:ElementUI = baseUI.add(mySprite);
  4. element.refresh();
  5. addChild(mySprite);

Actionscript:
  1. baseUI.remove(mySprite);
  2. baseUI.removeAll();

Getting ElementUI instances

Actionscript:
  1. var element:ElementUI = baseUI.getElement(mySprite);
  2. var arrayOfElements:Array = baseUI.getElements(); // note that this is a copy of the real array
  3. var dictionaryOfElements:Dictionary = baseUI.getElementsAsDictionary(); // note that this is a copy of the real dictionary

Setting ElementUI properties

Actionscript:
  1. var element:ElementUI = baseUI.getElement(mySprite);
  2. element.bottom = 10;
  3. element.right = 10;
  4. element.refresh();

Actionscript:
  1. var element:ElementUI = baseUI.getElement(mySprite);
  2. element.horizontalCenter = 0;
  3. element.verticalCenter = 0;
  4. element.refresh();

Actionscript:
  1. var element:ElementUI = baseUI.getElement(mySprite);
  2. element.ratio = ElementUI.RATIO_IN;
  3. element.refresh();

Reset ElementUI properties

You can reset the Number properties of the ElementUI instance by using NaN or null for the others:

Actionscript:
  1. element.top = 10;
  2. element.top = NaN;
  3.  
  4. element.ratio = ElementUI.RATIO_IN;
  5. element.ratio = null; // or Element.RATIO_NONE
  6.  
  7. element.rect = new Rectangle(0, 0, 50, 50);
  8. element.rect = null;

Or reset all of them:

Actionscript:
  1. element.reset();

Using ratio

The ratio is a kind of mode. You can use with a DisplayObject instance that keeps its proportion (Aspect Ratio) when it gets resized. Especially useful with pictures or backgrounds for example.

There is two ratio mode, a mode "in" and a mode "out".

The mode "in" will always display all the surface of the DisplayObject instance in its reference, you might get empty area if the reference has a different ratio.
The mode "out" will always cover the surface of the reference, you might miss some part of the DisplayObject if the reference has a different ratio.

ElementUI aspect ratio

Actionscript:
  1. var element:ElementUI = baseUI.add(mySprite);
  2. element.ratio = ElementUI.RATIO_IN;
  3. element.alignX = ElementUI.ALIGN_RIGHT;
  4. element.alignY = ElementUI.ALIGN_BOTTOM;

DisplayObject boundaries (optional)

When you use some ElementUI properties (such as right, bottom, horizontalCenter, etc), BaseUI will use the width and height of your DisplayObject instance to make its position calculation. For example, if you want the object to be at 10 pixels from the bottom, BaseUI needs to use the height.

This might prove difficult in some cases, for example if you have a specific "center point" or if the size of the DisplayObject instance changes all the time (if it is animated).

To solve this kind of problem, you can specify the boundaries of your DisplayObject to be used as a size in BaseUI instead of its real size. You can do that by using the "rect" and a Rectangle instance.

For example, if you draw a square in a sprite width 100 and height 100, but starting at x -50 and y -50 so it is centered. You can specify the boundaries like this:

Actionscript:
  1. var element:ElementUI = baseUI.add(myCenteredSprite);
  2. element.rect = new Rectangle(-50, -50, 100, 100);

And you can remove it this way:

Actionscript:
  1. element.rect = null;

ElementUI Listeners

An ElementUI instance can dispatch three events, in this order:

1. EventUI.WILL_CALCULATE (dispatched before any calculation)
2. EventUI.WILL_UPDATE (dispatched after calculation and before updating the DisplayObject)
3. EventUI.UPDATED (dispatched after that the DisplayObject has been updated)

You can stop the ElementUI process in the EventUI.WILL_CALCULATE and EventUI.WILL_UPDATE handlers using "event.preventDefault()".

Actionscript:
  1. var baseUI:BaseUI = new BaseUI(stage);
  2. var element:ElementUI = baseUI.add(mySprite);
  3. element.addEventListener(EventUI.WILL_CALCULATE, willCalculateHandler);
  4. element.addEventListener(EventUI.WILL_UPDATE, willUpdateHandler);
  5. element.addEventListener(EventUI.UPDATED, updatedHandler);
  6. element.right = 10;
  7. element.bottom = 10;
  8. element.refresh();
  9. addChild(mySprite);
  10.  
  11. private function willCalculateHandler(event:EventUI):void {
  12.     //event.preventDefault(); // stop the process before the calculation
  13.     trace(event.element); // trace the ElementUI instance
  14.     trace(event.element.object); // trace the DisplayObject instance
  15.     trace(event.element.baseUI); // trace the BaseUI instance
  16. }
  17.  
  18. private function willUpdateHandler(event:EventUI):void {
  19.     //event.preventDefault(); // stop the process before new properties are applied to the DisplayObject
  20.     trace(event.element); // trace the ElementUI instance
  21.     trace(event.element.object); // trace the DisplayObject instance
  22.     trace(event.element.baseUI); // trace the BaseUI instance
  23.     trace(event.properties); // trace the properties that will be applied to the DisplayObject
  24. }
  25.  
  26. private function updatedHandler(event:EventUI):void {
  27.     trace(event.element); // trace the ElementUI instance
  28.     trace(event.element.object); // trace the DisplayObject instance
  29.     trace(event.element.baseUI); // trace the BaseUI instance
  30.     trace(event.properties); // trace the properties that have been applied to the DisplayObject
  31. }

Refreshing an element

When you create an element, the position and size will be calculated when an Event.RESIZE occurs, which might not happen unless you resize your browser. For a performance matter, the calculation is not done when you change a property. To make the calculation and update your element, you might need to use the refresh method of your ElementUI instance (or BaseUI instance for all the ElementUI).

Actionscript:
  1. element.refresh();
  2. baseUI.refresh();

Disposing and garbage collection

Both BaseUI and ElementUI classes have a dispose method to destroy variables and make the instance eligible for the garbage collection. The only one you have to care about is the BaseUI one, as the ElementUI will be properly destroyed when you use the remove and removeAll BaseUI methods.

Actionscript:
  1. baseUI.dispose();
  2. baseUI = null;

Using layouts

Five layouts classes are built in BaseUI, all of them have ElementUI properties directly accessible.

- The LayoutUI class: the super class of all the other layouts classes, only a container, children stay un-touched
- The CanvasUI class: handle the children with ElementUI properties
- The HBoxUI class: display the children, one after the other, in a horizontal direction
- The VBoxUI class: display the children, one after the other, in a vertical direction
- The TileUI class: display the children, one after the other, and is in both direction and in a "multiline" way

All the layouts classes will have some common properties, such as background color, background transparency, rounded values, and if the content that goes outside of the boundaries of the layouts should be displayed or hidden.

You can also use layouts in other layouts, like adding canvas in tiles that are added in vertical boxes, etc. Be aware that we're still using flash here, and even if the library is efficient, it might get slower if you add thousands of tiles in thousands of other tiles with thousands of bitmaps. Calculation are made and everything has limits, especially Flash. Beside that, I got good performance with the library, you will be fine unless you do crazy things :)

The LayoutUI class

The LayoutUI class extends the MovieClip class and is nothing else that a container that will always have a size (width and height), even if there's nothing inside. Another difference with another built-in flash container (like Sprite, MovieClip, etc), is that the width and height will always be the one of the container regardless of what it contains.

For example, a layout instance (width 100 and height 100), that contains another DisplayObject (width 200 and height 200). The width and height values returned by a normal Sprite or MovieClip would be 200, while the layouts classes will return 100 (see getRealWidth and getRealHeight methods).

And that is true for all the layouts in the library, it is something to be aware of.

Actionscript:
  1. var layout:LayoutUI = new LayoutUI(stage, 400, 300);
  2. layout.backgroundColor = 0xFF0000;
  3. layout.backgroundAlpha = 0.2;
  4. layout.bottom = 10;
  5. layout.right = 10;
  6. layout.refresh();
  7. addChild(layout);

The CanvasUI class

The behavior of the CanvasUI class is very close to its super class (LayoutUI), with the different that an ElementUI instance is created (or removed) when you add children to its display list. Makes you able to handle the children of the CanvasUI instance with ElementUI properties.

Actionscript:
  1. var canvas:CanvasUI = new CanvasUI(stage, 400, 300);
  2. canvas.backgroundColor = 0xFF0000;
  3. canvas.backgroundAlpha = 0.2;
  4. canvas.ratio = ElementUI.RATIO_IN;
  5. addChild(canvas);
  6.  
  7. var sprite:Sprite = new Sprite();
  8. sprite.graphics.beginFill(0xFF0000, .5);
  9. sprite.graphics.drawRect(0, 0, 100, 100);
  10.  
  11. var element:ElementUI = canvas.add(sprite);
  12. element.right = 10;
  13. element.bottom = 10;
  14.  
  15. canvas.refresh();

The HBoxUI class (horizontal box)

The goal of the HBoxUI class is that it will take from the positioning of its children, and align them in an horizontal way and only one row. Properties such as children gap, children align and children padding are introduced.

Actionscript:
  1. var hbox:HBoxUI = new HBoxUI(stage, 400, 300);
  2. hbox.backgroundColor = 0xFF0000;
  3. hbox.backgroundAlpha = 0.2;
  4. hbox.ratio = ElementUI.RATIO_IN;
  5. hbox.childrenGap = new GapUI(5, 5);
  6. hbox.childrenPadding = new PaddingUI(5, 5, 5, 5);
  7. hbox.childrenAlign = HBoxUI.ALIGN_BOTTOM_RIGHT;
  8. addChild(hbox);
  9.  
  10. for (var i:int=0; i&lt;8; ++i) {
  11. var sprite:Sprite = new Sprite();
  12. sprite.graphics.beginFill(0xFF0000, .5);
  13. sprite.graphics.drawRect(0, 0, 100, 100);
  14. hbox.addChild(sprite);
  15. }
  16.  
  17. hbox.refresh();

The VBoxUI class (vertical box)

The VBoxUI class is much like the HBoxUI one, but you found out, in a vertical way.

Actionscript:
  1. var vbox:VBoxUI = new VBoxUI(stage, 400, 300);
  2. vbox.backgroundColor = 0xFF0000;
  3. vbox.backgroundAlpha = 0.2;
  4. vbox.ratio = ElementUI.RATIO_IN;
  5. vbox.childrenGap = new GapUI(5, 5);
  6. vbox.childrenPadding = new PaddingUI(5, 5, 5, 5);
  7. vbox.childrenAlign = VBoxUI.ALIGN_BOTTOM_RIGHT;
  8. addChild(vbox);
  9.  
  10. for (var i:int=0; i&lt;8; ++i) {
  11. var sprite:Sprite = new Sprite();
  12. sprite.graphics.beginFill(0xFF0000, .5);
  13. sprite.graphics.drawRect(0, 0, 100, 100);
  14. vbox.addChild(sprite);
  15. }
  16.  
  17. vbox.refresh();

The TileUI class

A kind of mix between the HBoxUI and VBoxUI classes, Flex developer are used to it as well. It will show the children in multiple lines, in any direction depending of the setting used.

Actionscript:
  1. var tile:TileUI = new TileUI(stage, 400, 300);
  2. tile.backgroundColor = 0xFF0000;
  3. tile.backgroundAlpha = 0.2;
  4. tile.ratio = ElementUI.RATIO_IN;
  5. tile.childrenGap = new GapUI(5, 5);
  6. tile.childrenPadding = new PaddingUI(5, 5, 5, 5);
  7. tile.childrenAlign = TileUI.ALIGN_BOTTOM_RIGHT;
  8. tile.childrenDirection = TileUI.DIRECTION_HORIZONTAL;
  9. addChild(tile);
  10.  
  11. for (var i:int=0; i&lt;16; ++i) {
  12. var sprite:Sprite = new Sprite();
  13. sprite.graphics.beginFill(0xFF0000, .5);
  14. sprite.graphics.drawRect(0, 0, 100, 100);
  15. tile.addChild(sprite);
  16. }
  17.  
  18. tile.refresh();

I'm sure you will enjoy the library, it is very easy to use. Please send me some feedback :)

Happy development!

Romuald

  • Digg
  • del.icio.us
  • Facebook
  • email
  • Netvibes
  • RSS
  • Twitter
Vote in HexoSearch

Comments 8 Comments »

I found out that there's a bug with the badge used to install an AIR application with Firefox from version 3.6.4 until today's version (3.6.6).

If you don't have the AIR runtime installed a Adobe UI should pop up to show a progress bar and install the runtime. The trouble is that nothing happened at all after clicking on the YES button.

Badge AIR runtime installation

To test the bug, uninstall your AIR runtime and test the badge in this page.

The problems is very inconsistent, sometimes it works and sometimes it doesn't.

I haven't been able to find out what's going on, so I reported the bug in this page.

Romu

  • Digg
  • del.icio.us
  • Facebook
  • email
  • Netvibes
  • RSS
  • Twitter
Vote in HexoSearch

Comments 1 Comment »