topical media & game development
lib-present-graphic-imagination-com-neave-imagination-NeaveImagination.ax
lib-present-graphic-imagination-com-neave-imagination-NeaveImagination.ax
[swf]
flex
Neave Imagination ...big wobbly elephants
Copyright (C) 2008 Paul Neave
http://www.neave.com/
@author Paul Neave
@version 1.0.0
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation at http://www.gnu.org/licenses/gpl.html
package // com.neave.imagination
{
import flash.display.*;
import flash.events.*;
import flash.filters.*;
import flash.geom.*;
// import com.neave.link.*;
public class @ax-lib-present-graphic-imagination-com-neave-imagination-NeaveImagination
{
// Main constants
private const RED_STEP:Number = 0.02;
private const GREEN_STEP:Number = 0.015;
private const BLUE_STEP:Number = 0.025;
private const MAX_LENGTH:int = 80;
private const SPREAD_MIN:int = 1;
private const SPREAD_MAX:int = 40;
// Main variables
private var container:DisplayObjectContainer;
private var stage:Stage;
private var canvasWidth:int;
private var canvasHeight:int;
private var list:Array;
private var px:Number;
private var py:Number;
private var size:Number;
private var spread:int;
private var paused:Boolean;
private var red:Number;
private var green:Number;
private var blue:Number;
private var lines:Shape;
private var bmp:Bitmap;
private var blackBitmap:BitmapData;
private var m:Matrix;
private var p:Point;
private var blur:BlurFilter;
private var link:lib_present_graphic_imagination_com_neave_link_NeaveLink;
Creates a new instance of Neave Imagination on the stage
@param container The display object (sprite or movieclip) to contain Neave Imagination
public function @ax-lib-present-graphic-imagination-com-neave-imagination-NeaveImagination(container:DisplayObjectContainer, width:int = 770, height:int = 400)
{
this.container = container;
stage = container.stage;
canvasWidth = width;
canvasHeight = height;
initStage();
initLines();
initBitmap();
initLink();
setFullScreenQuality();
}
Sets up stage listeners
private function initStage():void
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.addEventListener(Event.RESIZE, stageResizeListener);
stage.addEventListener(Event.MOUSE_LEAVE, mouseLeaveListener);
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveListener);
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownListener);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpListener);
stage.addEventListener(FullScreenEvent.FULL_SCREEN, setFullScreenQuality);
stage.addEventListener(Event.ENTER_FRAME, update);
}
Sets up line variables
private function initLines():void
{
list = new Array();
px = py = size = 0;
spread = SPREAD_MAX;
paused = false;
// Start using red
red = 0;
green = 255;
blue = 255;
// The main lines shape
lines = new Shape();
}
Creates a link to Neave.com above the bitmap
private function initLink():void
{
if (link) link.destroy();
link = new lib_present_graphic_imagination_com_neave_link_NeaveLink(container, canvasWidth, canvasHeight);
}
Sets up the main bitmap
private function initBitmap():void
{
// Stage sizes
var sw:int = stage.stageWidth;
var sh:int = stage.stageHeight;
var sw2:int = Math.ceil(sw / 2);
var sh2:int = Math.ceil(sh / 2);
// Create the main bitmap to draw into (and half the size to run faster)
bmp = new Bitmap(new BitmapData(sw2, sh2, false, 0xFF000000));
bmp.smoothing = true;
bmp.scaleX = bmp.scaleY = 2;
bmp.x = (canvasWidth - sw) / 2;
bmp.y = (canvasHeight - sh) / 2;
container.addChild(bmp);
// Create bitmap data for fading into black
blackBitmap = new BitmapData(sw2, sh2, false, 0xFF000000);
// Bitmap is moved over into position then halved in size to run faster
m = new Matrix();
m.translate(-bmp.x, -bmp.y);
m.scale(0.5, 0.5);
// Origin and blur filter
p = new Point(0, 0);
blur = new BlurFilter(4, 4, 1);
}
Draws the line animation
private function drawLines():void
{
// Clear the graphics before we draw the lines
var g:Graphics = lines.graphics;
g.clear();
g.moveTo(px, py);
// Draw a curve through all points in the list
for (var i:int = list.length - 1; i > 0; i--)
{
// Animate the lines outwards
list[i].x += list[i].dx;
list[i].y += list[i].dy;
// Draw the curve, fading out the last 8 points with alpha
g.lineStyle(list[i].size, list[i].color, (list.length > (MAX_LENGTH - 8) && i < 8) ? i / 8 : 1);
g.curveTo(list[i].x, list[i].y, (list[i].x + list[i - 1].x) / 2, (list[i].y + list[i - 1].y) / 2);
// Remove the last point from the list if we've reached the maximum length
if (list.length > MAX_LENGTH) list.splice(0, 1);
}
}
Draws the lines into the bitmap with a fade effect
private function drawBitmap():void
{
// Repeatedly fade out and blur the lines then draw in the new ones
var b:BitmapData = bmp.bitmapData;
b.lock();
b.merge(blackBitmap, b.rect, p, 4, 4, 4, 0);
b.applyFilter(b, b.rect, p, blur);
b.draw(lines, m, null, BlendMode.ADD);
b.unlock();
}
Listens for when the mouse leaves the stage
private function mouseLeaveListener(e:Event):void
{
paused = true;
}
Listens for when the mouse re-enters the stage
private function mouseMoveListener(e:MouseEvent):void
{
paused = false;
}
Listens for mouse press
private function mouseDownListener(e:MouseEvent):void
{
// Allow a kind of drawing-mode when mouse is pressed
spread = SPREAD_MIN;
}
Listens for mouse press
private function mouseUpListener(e:MouseEvent):void
{
// Spread lines out when mouse is released
spread = SPREAD_MAX;
}
Frees up memory by disposing all bitmap data
private function disposeBitmaps():void
{
bmp.bitmapData.dispose();
bmp.bitmapData = null;
blackBitmap.dispose();
blackBitmap = null;
}
Removes Neave Imagination and all other objects
public function destroy():void
{
stage.removeEventListener(Event.RESIZE, stageResizeListener);
stage.removeEventListener(Event.MOUSE_LEAVE, mouseLeaveListener);
stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveListener);
stage.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownListener);
stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpListener);
stage.removeEventListener(FullScreenEvent.FULL_SCREEN, setFullScreenQuality);
stage.removeEventListener(Event.ENTER_FRAME, update);
container.removeChild(bmp);
disposeBitmaps();
link.destroy();
}
Listens for stage resize
private function stageResizeListener(e:Event):void
{
// Start again with the bitmap if the stage is resized
container.removeChild(bmp);
disposeBitmaps();
initBitmap();
initLink();
}
Use low quality for full-screen mode otherwise Flash Player crashes after a few seconds!
private function setFullScreenQuality(e:FullScreenEvent = null):void
{
stage.quality = stage.displayState == StageDisplayState.FULL_SCREEN ? StageQuality.LOW : StageQuality.HIGH;
}
Updates the animation
private function update(e:Event):void
{
if (paused) return;
// Line movement is set by how much the mouse has moved since its previous position and a random value
var dx:Number = (container.mouseX - px + Math.random() * 4 - 2) / 2;
var dy:Number = (container.mouseY - py + Math.random() * 4 - 2) / 2;
// Limit the amount of movement
if (dx < -spread) dx = -spread;
if (dx > spread) dx = spread;
if (dy < -spread) dy = -spread;
if (dy > spread) dy = spread;
// Store the mouse position
px = container.mouseX;
py = container.mouseY;
// Line thickness varies up and down with sine
var s:Number = Math.sin(size += 0.2) * 8 + 4;
// Put the red, green and blue values together into a single hexadecimal value
var c:uint = (Math.sin(red += RED_STEP) * 128 + 127) << 16
| (Math.sin(green += GREEN_STEP) * 128 + 127) << 8
| (Math.sin(blue += BLUE_STEP) * 128 + 127);
// Create a new point on the line
list.push(new lib_present_graphic_imagination_com_neave_imagination_ImaginationPoint(px, py, dx, dy, s, c));
// Draw!
drawLines();
drawBitmap();
}
}
}
(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.