topical media & game development
#graphic-flex-image-effects-11-Flex-MothFlowers.ax
#graphic-flex-image-effects-11-Flex-MothFlowers.ax
[swf]
[flash]
flex
package {
import aether.utils.ImageUtil;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.filters.BitmapFilterQuality;
import flash.filters.BitmapFilterType;
import flash.filters.GradientGlowFilter;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Rectangle;
import flash.utils.ByteArray;
[SWF(width=400, height=300, backgroundColor=0x000000)]
Draws the raw sound wave of a loaded sound playing in a circular pattern with
filters applied onto multiple planes that are rotates in 3D space. These planes
are then drawn into bitmap data and visually flipped in a mirror effect, creating
symmetrical shapes.
public class @ax-graphic-flex-image-effects-11-Flex-MothFlowers extends Sprite {
// the radius of the main circular pattern drawn onto the planes
private const WAVE_RADIUS:uint = 250;
// the colors used for the visualization
private const WAVE_COLORS:Array = [0xFFFF66, 0xFFFFFF, 0x666699];
private var _soundController:graphic_flex_image_effects_11_Flex_SoundController;
private var _planes:Vector.<Bitmap>;
private var _planesHolder:Sprite;
private var _drawingPlane:Sprite;
private var _drawingShape:Shape;
private var _background:Bitmap;
private var _backgroundShape:Shape;
Constructor. Creates assets in which the visualization will be drawn and loads sound.
public function @ax-graphic-flex-image-effects-11-Flex-MothFlowers() {
makeBackground();
makeDrawingPlane();
makePlanes();
_soundController = new graphic_flex_image_effects_11_Flex_SoundController("graphic-flex-image-effects-11-assets-SunriseStay.mp3");
_soundController.addEventListener(Event.CHANGE, onSoundChange);
}
Creates background bitmap and background shape and places these on stage.
private function makeBackground():void {
// black shape will be drawn over previous rendering at low opacity to create ghosting effect
_backgroundShape = new Shape();
_backgroundShape.graphics.beginFill(0);
_backgroundShape.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
_backgroundShape.graphics.endFill();
addChild(_backgroundShape);
_background = new Bitmap();
addChild(_background);
}
Creates a single plane (sprite) into which a sound visualization will be drawn.
This is a nested shape within a sprite. A gradient glow filter is also applied.
private function makeDrawingPlane():void {
_drawingPlane = new Sprite();
_drawingShape = new Shape();
_drawingShape.x = stage.stageWidth/2;
_drawingShape.y = stage.stageHeight/2;
_drawingPlane.addChild(_drawingShape);
_drawingPlane.filters = [
new GradientGlowFilter(
5,
45,
WAVE_COLORS,
[0, 1, 1],
[0, 180, 255],
2,
2,
1,
BitmapFilterQuality.MEDIUM,
BitmapFilterType.FULL,
true
)
];
}
Creates the three planes. These each consists of a bitmap within a sprite, the nested nature making
it easier to transform the image from a central registration point. All planes are held within a single
sprite. Each plane in rotated at a different angle around the y axis.
private function makePlanes():void {
_planes = new Vector.<Bitmap>();
_planesHolder = new Sprite();
var plane:Bitmap;
var planeHolder:Sprite;
// used to center the sprites and their nested bitmaps
var x:Number = stage.stageWidth/2;
var y:Number = stage.stageHeight/2;
var numPlanes:uint = 3;
for (var i:uint = 0; i < numPlanes; i++) {
plane = new Bitmap();
// offsetting by the halfwidth/halfheight will allow parent to be rotated
// with the effect being that this bitmap is rotated around its center
plane.x = -x;
plane.y = -y;
planeHolder = new Sprite();
planeHolder.x = x;
planeHolder.y = y;
// difference mode creates interesting colors
planeHolder.blendMode = BlendMode.DIFFERENCE;
planeHolder.addChild(plane);
// results in all three planes being equally rotated in full circle
planeHolder.rotationY = i*(180/numPlanes);
_planes.push(plane);
_planesHolder.addChild(planeHolder);
}
}
Updates the main visualization with new sound data. This draws into the main
drawing shape, which will have its data copied into each plane.
private function updateDrawingShape():void {
// raw sound wave data is captured
var spectrumData:ByteArray = _soundController.getSoundSpectrum(false);
_drawingShape.graphics.clear();
_drawingShape.graphics.lineStyle(1, 0xFFFFFF);
var x:Number;
var y:Number;
var i:int = -1;
var value:Number;
var angle:Number;
while (++i < 512) {
// value is scaled to be within WAVE_RADIUS value
value = Math.ceil(WAVE_RADIUS*spectrumData.readFloat());
// each value will be drawn at different angle around full circle
angle = i/512*Math.PI*2;
x = Math.cos(angle)*value;
y = Math.sin(angle)*value;
_drawingShape.graphics.moveTo(0, 0);
_drawingShape.graphics.lineTo(x, y);
}
}
Updates each of the planes with the new drawn data.
private function updatePlanes():void {
var width:Number = stage.stageWidth;
var height:Number = stage.stageHeight;
// captures the pixel data of the drawing plane
var capture:BitmapData = new BitmapData(width, height, true, 0x00000000);
capture.draw(_drawingPlane);
// draws data into each plane
for each (var bitmap:Bitmap in _planes) {
bitmap.bitmapData = capture.clone();
}
}
Updates the background bitmap data with current visuals on the stage, scaled up and
set at a low opacity over the previous rendering.
private function updateBackground():void {
// capture pixels from all three planes
var capture:BitmapData = ImageUtil.getBitmapData(_planesHolder);
var matrix:Matrix = new Matrix();
// used to flip image horizontally
matrix.scale(-1, 1);
matrix.translate(width, 0);
// only need to draw half of flipped data to get mirrow effect
var rect:Rectangle = new Rectangle(0, 0, width/2, height);
var halfData:BitmapData = capture.clone();
// fill half of cloned image with transparent pixels
capture.fillRect(rect, 0x00000000);
// fill other half with flipped image
capture.draw(halfData, matrix, null, null, rect);
// get last rendering on stage
var stageCapture:BitmapData = ImageUtil.getBitmapData(this);
// draw black shape at low opacity to reveal previous renderings
stageCapture.draw(_backgroundShape, null, new ColorTransform(1, 1, 1, .3));
// draw new symmetrical image
stageCapture.draw(capture);
_background.bitmapData = stageCapture;
}
Handler for when the sound changes (basically, an ENTER_FRAME while the sound is playing).
This calls the update methods in this class to redraw visualization.
parameter: event Event dispatched by SoundController.
private function onSoundChange(event:Event):void {
updateDrawingShape();
updatePlanes();
updateBackground();
}
}
}
(C) Æliens
04/09/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.