O2 BlackBerry Curve Banner
For the release of the purple BlackBerry Curve on O2 VCCP made a stunning and simple print ad. My role was to recreate and animate that in a set of banners.
The concept
I love it when things are this simple. The BlackBerry Curve is available in purple. The phone color is emphasised with an explosion of make-up powder. Awesome :-).
It’s all down to the explosion
The storyboard can be divided into three parts.
- The phone drops
- The powder explodes with the phone&rsquos; impact
- Show the end screen
The falling phone uses a simple Greensock tween. The fun really starts with the explosion. To get a realistic animation Flint is really useful.
If you are interested in code…
The Content class holds the whole composition together. This is where the PurplePuff is added.
protected var _puff:PurplePuff; … var ex:Number = _model.width/2; var ey:Number = _model.height/2; … _puff = new PurplePuff(ex+_phoneHorizontalOffset, ey+_phoneOffset, _puffScale, 0.2, _freeze); _puff.x = -ex; _puff.y = -ey; _holder.addChild(_puff); … // start purple explosion _puff.init();
The PurplePuff class add a bunch of custom emitters and some randomly selected brush bitmaps I made in Photoshop and added to the Flash IDE library.
package uk.o2.banner.view
{
import …
/**
* @author ajbis
*/
public class PurplePuff extends Sprite
{
private var _renderer:BitmapRenderer;
private var _blur:BlurFilter;
private var _int:uint;
private var _brush:Array = [];
private var _shadow:Bitmap;
private var _x:Number;
private var _y:Number;
private var _scale:Number;
private var _friction:Number;
private var _freeze:Number;
public function PurplePuff(ex:Number = 0, ey:Number = 0, scale:Number = 1, friction:Number = 1, t:Number = 750)
{
_x = ex;
_y = ey;
_scale = scale;
_friction = friction;
_freeze = t;
addBrushes();
addShadow();
addRenderer();
addAllEmitters();
}
public function init():void
{
for (var i:uint = 0; i<_renderer.emitters.length; i++)
{
_renderer.emitters[i].addBlast(_scale, _friction);
_renderer.emitters[i].start();
}
_int = setTimeout(stopBlur, _freeze);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function addBrushes():void
{
_brush[0] = new Brush0();
_brush[1] = new Brush1();
_brush[2] = new Brush2();
_brush[3] = new Brush3();
_brush[4] = new Brush4();
}
private function addShadow():void
{
_shadow = new Bitmap();
addChild(_shadow);
var tran:Color = new Color();
tran.setTint(0x3A1392, 1);
_shadow.transform.colorTransform = tran;
}
private function addRenderer():void
{
var model:Model = Model.getModel();
_renderer = new BitmapRenderer(new Rectangle(-10*_scale, -10*_scale, model.width+(20*_scale), model.height+(20*_scale)), true);
_blur = new BlurFilter(30*_scale, 30*_scale, 1);
_renderer.addFilter(_blur);
addChild(_renderer);
}
private function addAllEmitters():void
{
addEmitter(12, 200, 0.6);
addEmitter(12, 150, 1);
addEmitter(25, 100, 2);
addEmitter(12, 200, 0.4);
addEmitter(12, 200, 0.6);
addEmitter(12, 150, 1);
addEmitter(25, 100, 2);
addEmitter(12, 200, 0.4);
addEmitter(12, 200, 0.6);
addEmitter(12, 150, 1);
addEmitter(25, 100, 2);
addEmitter(12, 200, 0.4);
addEmitter(12, 200, 0.6);
addEmitter(12, 150, 1);
addEmitter(25, 100, 2);
addEmitter(12, 200, 0.4);
}
private function addEmitter(p:uint, v:Number, s:Number, brush:Brush = null):void
{
var emitter:PinkPuffEmitter = new PurplePuffEmitter(p, v, s, brush == null ? _brush[Math.floor(Math.random()*4)] : brush);
emitter.x = _x;
emitter.y = _y;
_renderer.addEmitter(emitter);
}
private function stopBlur():void
{
clearTimeout(_int);
for (var i:uint = 0; i<_renderer.emitters.length; i++) _renderer.emitters[i].stop();
removeEventListener(Event.ENTER_FRAME, onEnterFrame);
}
public function reset():void
{
alpha = 1;
visible = true;
_renderer.bitmapData.fillRect(_renderer.bitmapData.rect, 0);
}
private function onEnterFrame(event:Event):void
{
_shadow.bitmapData = _renderer.bitmapData;
_shadow.alpha = 0.4;
}
}
}
Finally, the custom emitter uses Flint’s Blast counter.
package uk.o2.banner.view
{
import …
/**
* @author ajbis
*/
public class PurplePuffEmitter extends Emitter2D
{
private var _p:uint; // particles
private var _v:Number; // velocity
private var _s:Number; // size
private var _brush:Brush;
public function PurplePuffEmitter(p:uint, v:Number, s:Number, brush:Brush = null)
{
super();
_p = p;
_v = v;
_s = s;
_brush = brush;
}
public function addBlast(scale:Number, friction:Number):void
{
counter = new Blast(_p);
addInitializer(new SharedImage(_brush));
addInitializer(new ColorInit(0xFFD44FA3, 0x3A1392));
addInitializer(new Position(new PointZone(new Point(0, 0))));
addInitializer(new Velocity(new DiscZone(new Point(Math.random()*10-5, Math.random()*10-5), _v*2*scale, 50*scale)));
addInitializer(new ScaleImageInit(0.05*scale, _s*scale));
addInitializer(new Rotation(0, 360));
addAction(new Move());
addAction(new RandomDrift(3*scale, 3*scale));
addAction(new Friction(_v*friction*(1/scale)));
}
}
}
All up the banner is 80k. Where possible the different formats share code. There’s a MPU, skyscraper, wide skyscraper, rectangle (180 x 150px), leaderboard and half banner. To squeeze a few extra kilobytes the supplied bubble bounce at the end was converted to code too. For those of you with Flash Player installed you can see the skyscraper and MPU.
