Jan 13
Create BitmapData Objects from an Array of image URLs - very kool and useful
I wrote this very reusable class called the “CreateBitmapData” class a little while back. I’ve used it in multiple projects and it has saved me countless hours and natural hair color. Basically you pass and Array of image URLs and a callback function expecting an Array of BitmapData Objects and it’s as easy as that. It utilizes the built in MovieClipLoader class and will push in an undefined value into the returning Array if there is an error loading the image. This is a failsafe so that it doesn’t completely break whatever you are doing. I will try to have an AS3 version for it soon. Check it out, let me know if you make any modifications.
How to use it:
//—————————————————
import CreateBitmapData;
var objCreateBitmapData:CreateBitmapData = new CreateBitmapData();
function bitmapsReciever($bitmaps:Array){
// Do what you want with the BitmapData Objects Array here.
}
objCreateBitmapData.create([”http://www.example.com/pic1.jpg”,”http://www.example.com/pic2.jpg”], {scope: this, func:”bitmapsReciever”})
//—————————————————
Here’s what the code actually looks like if your interested:
/*
Author: Charles D Clements copyright 2007
Email: charlesdclements@yahoo.com
WebSite: www.charlesclements.net
Pass an Array of image paths into this class and it will return an Array with all the
BitmapData Objects created into the specified return object as a parameter.
*/
import flash.display.BitmapData;
class CreateBitmapData {
/*
Variables
*/
// MovieClips
private var mcContainer:MovieClip;
private var mcInnerContainer:MovieClip;
// MovieClipLoader
private var objMovieClipLoader:MovieClipLoader;
// Numbers
private var numIncrement:Number = -1;
// Arrays
private var arrImageStrings:Array = [];
private var arrNewBitmaps:Array = [];
// Strings
private var strClassName:String = “CreateBitmapData”;
// Objects
private var objCallback:Object;
/*
Constrructor
*/
public function CreateBitmapData() {
trace(’CreateBitmapData’);
this.arrImageStrings = [];
this.arrNewBitmaps = [];
}
/*
Creates BitmapData from external Images.
$array: an Array of external image URLs.
$callbackObj: an Object containing a scope and a callback function in which it returns an Array of BitmapData Objects to.
The callback function should be expacting an Array.
———————————————————
ex: objCreateBitmapData.create([”http://www.example.com/pic1.jpg”,”http://www.example.com/pic2.jpg”], {scope: this, func:”bitmapsCreated”})
*/
public function create($array:Array, $callbackObj:Object):Void {
trace(’create’);
this.arrImageStrings = $array;
this.objCallback = $callbackObj;
this.mcContainer = _root.createEmptyMovieClip(”mcContainer”, _root.getNextHighestDepth());
this.mcContainer._visible = false;
this.loadImages();
}
/*
Load external images from Array.
*/
private function loadImages():Void {
this.numIncrement++;
if (this.numIncrement < this.arrImageStrings.length) {
this.mcInnerContainer = this.mcContainer.createEmptyMovieClip(”mcInnerContainer”, 0);
this.objMovieClipLoader = new MovieClipLoader();
this.objMovieClipLoader.addListener(this);
(this.arrImageStrings[this.numIncrement] == undefined) ? this.spotTaken() : this.loadClip(this.arrImageStrings[this.numIncrement], this.mcInnerContainer);
} else {
this.done();
}
}
/*
Local loadClip() function that calls the MovieClipLoader loadClip() function.
*/
private function loadClip($URL:String, $container:MovieClip):Void {
this.objMovieClipLoader.loadClip($URL,$container);
}
/*
*/
private function onLoadError(target_mc:MovieClip, errorCode:String, httpStatus:Number):Void {
trace(”>> loadListener.onLoadError()”);
trace(”>> ==========================”);
trace(”>> errorCode: ” + errorCode);
trace(”>> httpStatus: ” + httpStatus);
this.spotTaken();
}
/*
If the URL is undefined this inserts an undefined into the Array to be returned.
*/
private function spotTaken():Void {
this.arrNewBitmaps.push(undefined);
this.loadImages();
}
/*
Listens for when the image has loaded.
*/
private function onLoadInit($clip:MovieClip):Void {
var bmd:BitmapData = new BitmapData(this.mcContainer._width, this.mcContainer._height, true, 0×00000000);
bmd.draw(this.mcContainer);
this.arrNewBitmaps.push(bmd);
this.loadImages();
}
/*
Called when all images have been loaded.
*/
private function done():Void {
this.bitmapDataCreated();
this.clear();
}
/*
Load external images by passing an Array.
*/
private function clear():Void {
this.numIncrement = -1;
this.arrImageStrings = [];
this.arrNewBitmaps = [];
this.mcContainer.removeMovieClip();
}
/*
Load external images by passing an Array.
*/
public function getBitmaps():Array {
return (this.arrNewBitmaps);
}
/*
Calls the Callback passed into the setup.
*/
private function bitmapDataCreated():Void {
this.objCallback.scope[this.objCallback.func](this.getBitmaps());
}
}
Jan 13
UserInteraction class - sets off a timer after you leave a designated user area onstage and fires a callback a function. Very useful for banners.
Where I work we do alot of banners. I wrote a class a while back that has come in handy multitudes of times. It contains a handful of public functions and I’ve used it on many major advertising banner campaigns (various HP banners, Snickers – Get Some Nuts, Toyota Sequoia, etc).
EXAMPLE SITUATIONS:
- Suppose you want to set a timer after a user has rolled out of a banner and then call a function to have an animation play out to the end once the time is up.
- Suppose you want a popup window in your website to remain open for 3 seconds after the user has left the hit area, and then close. But if the user rolls over the area before the time is up the user interaction area resets itself.
HOW TO USE IT:
//—————————————————————————
import UserInteraction;
var objUserInteraction:UserInteraction = UserInteraction.getInstance();
function endFunc() {
trace(’endFunc called’);
objUserInteraction.reset();
}
objUserInteraction.setup({clip:mcClip, timer:3, show:true, timerCallback:{scope:this, func:”endFunc”}});
//—————————————————————————
- Import the class
- Create an instance of it
- Create a MovieClip of the desired hit state area and name it
- Create a function that the class will call at the end of timer
- Call the setup function
AVAILABLE PUBLIC FUNCTIONS:
METHOD
getInstance():UserInteraction
Creates a new instance of the class.
————————————–
METHOD
setup($obj:Object):Void
Passes all the necessary variables into class.
PARAMS
$obj : Pass an object of the following params:
clip: MovieClip that will be used as hit area.
timer: Time set in seconds.
timerCallback: Function that is called once the user has been out of the area for designated time.
rollOverCallback (optional): Function that can be called on rollover.
show (optional): When set to true will make the MovieClip visible at 50% alpha. Default is set to false.
————————————–
METHOD
reset():Void
This allows the hit area to be used again after the timer condition has been met.
————————————–
METHOD
stop():Void
This stops all functionality at work in the class and also hides hit area.
SIDE NOTES:
- You may want to keep the hit area a bit smaller than the actual target area especially with banners. This is suggested because if the user rolls out of the area too quick, Flash may think that the mouse is still over the hit area and the timer will not be started.
- Always scale the contents of a MovieClip and not the MovieClip as a whole from the outside. You may get undesired results other wise.
No comments
Jan 13
DisplacementMapFilter applied to MovieClip: Quick and Easy
THE EFFECT:
Of all of the filters that Flash has to offer, the DisplacementMapFilter holds a special place in my heart. If you don’t care about the WHY and only want the HOW scroll to the bottom.
THE STORY:
The following is a piece of history as I understood it while it was happening. You should question anyone else involved for the whole story. Here it goes:
We (ichameleon/group/) once got pulled into a project for HP because the client wasn’t happy with the way things were going with their current vendor. Although time was short, they decided to contact a list of other vendors to see who came up with the best solution. As eloquently as I can state it, the whole thing turned into an elaborate pissing contest between 7 other well known and respected vendors. They shall remain nameless because God forbid, I might need something from one of them one day. We ended up being the crowd favorite and delivered in a timely fashon as we always do.
WHAT I NEEDED:
The project required a streaming effect with images being pulled dynamic from the library and they had to warp like paper as they floated across the screen. We couldn’t use image sequences from AfterEffects because eventually this same stream engine needed to be used in a screensaver application that would pull images from the user’s hard drive and warp them dynamically in the same way. It was pretty kool!
God Bless Macromedia at the time for implementing the use of the DisplacementMapFilter in Flash 8. All filters in general for that matter. You can apply a DisplacementMapFilter to either BitmapData or to MovieClips. Filters applied to Bitmaps alter the Bitmap completely. It is like manipulating an image in PhotoShop and there is no undo. You can apply a filter to a MovieClip and it remains unaltered. The filters Array can be cleared and the MovieClip is the same as before anything was applied to it. The actual code that it takes to apply a filter is minimal yet powerful.
THE CODE – What it is:
DisplacementMapFilter(mapBitmap:BitmapData, mapPoint:Point, componentX:Number, componentY:Number, scaleX:Number, scaleY:Number, [mode:String], [color:Number], [alpha:Number])
The following is the bare minimum of what I use to create something kool:
mapBitmap: This is the BitmapData object that contains the displacement map data.
mapPoint: This is the positioning coordinates of the displacement map when it gets applied. You generally want to keep these points at 0,0 or less. If you use a large positive number like 50,50, you will notice part of the area gets the filter applied to it, and the rest of the area remains unchanged.
componentX/ componentY: These are the color channels that will be modified. The different channels are 1 (red), 2 (green), 4 (blue), and 8 (alpha). I’ve never been able to tell the difference when changing these values. I would leave it at 1.
scaleX/ scaleY: This is where the fun happens. These values determine how far a pixel gets displaced according to displacement map color shade.
Here is what the code looks like for the example:
——————————————————————————-
// Import classes
import flash.filters.DisplacementMapFilter;
import flash.display.BitmapData;
import flash.geom.Point;
// Create a BitmapData instance. The DisplacementMapFilter will need this.
var bpm1:BitmapData = new BitmapData(mcMap._width, mcMap._height, true);
// Create a DisplacementMapFilter instance. Pass the BitmapData instance in as the first parameter.
var dpmFilter:DisplacementMapFilter = new DisplacementMapFilter(bpm1, new Point(0, 0), 2, 2, 10, 10);
// Add the DisplacementMapFilter into the MovieClip’s “filters” Array.
mcClip.filters = [dpmFilter];
// Call the “draw()” method of the BitmapData class to continually update the DisplacementMap on the MovieClip.
mcClip.onEnterFrame = function() {
bpm1.draw(mcMap);
};
——————————————————————————-
PS: The example used an image sequence I created in AfterEffects because it would illustrate the power and koolness of the DisplacementMapFilter. I added the exact Bitmap sequence inside the affected MovieClip, masked it out to the size of the image and gave it a “MULTIPLY” blending mode for shadows and extra fanciness! Let me know what you think.
SIDE NOTES:
- You may want to always make the DisplacementMapFilter larger that the image/movieclip you will be affecting. You will notice a cutoff depending on how much the pixels will be displaced. Take my word for it.
- Anything that has contrasting color values (ex: balck/white) can be used as a displacement map. Images, image sequences, video, vector gradient fills, I would say ANYTHING.
Jan 13
JSFL – Guide / Unguide Selected Layers
JSFL is one of those magic features in Flash that could possibly change your life (or at least put a huge smile on your face). If you are like me and deal with multitudes of layers on a single timeline and use the “guide layers” functionality frequently, this post is for YOU!!!
Wouldn’t it be great if you could select 10 layers at once and set them all as guided. The way we have always done it till now is if there are multiple layers that need to be guided, we would have to select layer / right click / guide layer for each one individually. I wrote this script to handle that redundant task and I share it with you.
——————————————————————————-
/*
My favorite part about this script is that if you select guided layers along with unguided layers, their statuses will be toggled.
Title: Guide / Unguide Layers
Action: Guides selected unguided layers and vice versa.
Author: Charles D Clements
Date: 10/11/07
*/
// Create an Array of the layer indeces.
var layerArray = fl.getDocumentDOM().getTimeline().getSelectedLayers();
// Loop thru Array.
for(a = 0; a < layerArray.length; a++){
var numLayer = layerArray[a]
var thisLayer = fl.getDocumentDOM().getTimeline().layers[numLayer]
switch(thisLayer.layerType){
case ‘normal’:
thisLayer.layerType = “guide”;
break
case ‘guide’:
thisLayer.layerType = “normal”;
break
}
}
——————————————————————————-
Jan 13
JSFL – Colorize Selected Layers
When you start working projects with heavy timeline animations you learn real quick that is is best to be as organized as possible. I guess that is true in all aspects of life. Here is one small tool that will help. Colorize Selected Layers will take the layers selected and make all of the outlines a uniform color that you specify. The script is very short and sweet.
——————————————————————————-
/*
Action: Takes the layers selected and make all of the outlines a uniform color that you specify.
Author: Charles D Clements
Date: 10/11/07
*/
// Color var
var hex = prompt(”What color do you want the layers? ex: FF0022:”);
// Create an Array of the layer indeces.
var layerArray = fl.getDocumentDOM().getTimeline().getSelectedLayers();
// Loop thru Array of layers
for(a = 0; a < layerArray.length; a++){
fl.getDocumentDOM().getTimeline().layers[layerArray[a]].color=”#”+hex;
}
——————————————————————————-
Jan 13
JSFL - How to use JSFL
There are different ways you can use the JSFL scripts on this blog. I will list a few ways that you can get up and running.
1. Quick and dirty. If script is simple and doesn’t require XML (it will be only one AS file), this will work fine just to test it out.
- Create a new JSFL text file in Flash
- Paste in this code
- Save it to your harddrive
- Depending on the command you are trying to run, create the appropriate scenario that the script will be used for (ex: using the ‘Colorize Selected Layers’, you will need to create several layers and select the specified layers to be colorized)
- In the top menu go to Commands/Run Command, then navigate to the saved JSFL file and open it
- Done
2. Proper way. Stick the command file in the Flash Commands folder. This is helpful because the JSFL command will show up in the Commands drop down on the top menu and you won’t need to navigate to the file on your harddrive.
- Create a new JSFL text file in Flash
- Paste in this code
- Save it to or paste the file into the following directory on Windows: C:\Documents and Settings\”YOUR NAME”\Local Settings\Application Data\Adobe\Flash CS3\en\Configuration\Commands
- Restart Flash
- Depending on the command you are trying to run, create the appropriate scenario that the script will be used for (ex: using the ‘Colorize Selected Layers’, you will need to create several layers and select the specified layers to be colorized)
- Click on the Commands tab in the top navigation and look for the appropriate Command in the dropdown.
- Done
These are the 2 basic ways of using JSFL. I may do a post about packaging JSFL into an MXP file for easy installation at a later date.
Payce
2 comments