package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.BlendMode; import flash.display.PixelSnapping; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageQuality; import flash.display.StageScaleMode; import flash.events.Event; import flash.filters.BlurFilter; import flash.geom.Matrix; import flash.geom.Point; import flash.geom.Rectangle; import org.ascollada.utils.FPS; import org.papervision3d.cameras.Camera3D; import org.papervision3d.materials.ColorMaterial; import org.papervision3d.objects.primitives.Plane; import org.papervision3d.objects.special.VectorShape3D; import org.papervision3d.render.BasicRenderEngine; import org.papervision3d.scenes.Scene3D; import org.papervision3d.view.Viewport3D; import razor.utils.ColorUtils; import flash.events.MouseEvent; import gs.TweenLite; import fl.motion.easing.Quadratic; import flash.utils.Timer; import flash.events.TimerEvent; import flash.net.navigateToURL; import flash.net.URLRequest; [SWF(width="800", height="480", backgroundColor="0x000000", frameRate="35")] public class Blue extends Sprite { protected static const HSQUARES:int = 18; protected static const VSQUARES:int = 16; protected static const SQUARE_SIZE:int = 500; protected static const STEP:Number = 0.07; protected static const DOF:Boolean = false; protected static const BLUR_STEPS:Number = 2; protected static const MODE_CYCLE:uint = 1; protected static const MODE_BERRY:uint = 2; protected static const MODE_SPARKLY:uint = 3; protected static const MODE_WORLD:uint = 4; protected var bitmap:Bitmap; protected var bitmapData:BitmapData; protected var bitmapBuffer:BitmapData; protected var blitMatrix:Matrix; protected var depthFilter:BlurFilter; protected var viewport:Viewport3D; protected var renderer:BasicRenderEngine; protected var scene:Scene3D; protected var camera:Camera3D; protected var grid:Array; protected var berry:Array; protected var world:Array; protected var sparkles:Array; [Embed(source="../splat.png")] protected var splat:Class; [Embed(source="../bookmark.png")] protected var berry_png:Class; [Embed(source="../fl.png")] protected var world_png:Class; protected var count:Number = 0; protected var tweenCount:Number = 0; protected var colourMode:uint = MODE_BERRY; protected var tweenMode:uint = 0; protected var timer:Timer; public function Blue() { init(); } protected function init():void { stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; stage.quality = StageQuality.BEST; stage.addEventListener(MouseEvent.MOUSE_DOWN, onClick); //stage.addEventListener(Event.RESIZE, onResize); //var fps:FPS = new FPS(); bitmapData = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0); bitmapBuffer = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0); bitmap = new Bitmap(bitmapData, PixelSnapping.AUTO, false); addChild(bitmap); blitMatrix = new Matrix(); depthFilter = new BlurFilter(4,4,1); viewport = new Viewport3D(stage.stageWidth, stage.stageHeight, false, false, false, false); //viewport.filters = [ new BlurFilter(5,5,2) ]; //addChild(viewport); renderer = new BasicRenderEngine(); scene = new Scene3D(); camera = new Camera3D(); camera.z = -700; // 700 camera.y = -1950; camera.x = -3150; camera.target.x = -2985; camera.target.y = -1780; addEventListener(Event.ENTER_FRAME, render); initGrid(); initBerry(); initWorld(); //addChild(fps); var splat:Bitmap = new splat() as Bitmap; splat.x = stage.stageWidth - splat.width; addChild(splat); timer = new Timer(6000); timer.addEventListener(TimerEvent.TIMER, onTimer); timer.start(); } protected function initGrid():void { grid = new Array(); for (var j:int = 0; j < VSQUARES; j++) { for (var i:int = 0; i < HSQUARES; i++) { if (grid[i] == null) grid[i] = new Array(); //if (i + 2*j < 2 || i - 0.75*j > 9 // || i - 2.5*j < -18) // continue; var mat:ColorMaterial = new ColorMaterial(0x000090, 1, false); mat.doubleSided = false; var s:Plane = grid[i][j] = new Plane(mat, SQUARE_SIZE+2, SQUARE_SIZE+2); s.x = SQUARE_SIZE/2-HSQUARES*SQUARE_SIZE/2 + i*SQUARE_SIZE; s.y = SQUARE_SIZE/2-VSQUARES*SQUARE_SIZE/2 + j*SQUARE_SIZE; scene.addChild(s); } } } protected function initBerry():void { berry = new Array(); var img:Bitmap = new berry_png() as Bitmap; for (var j:int = 0; j < VSQUARES; j++) { for (var i:int = 0; i < HSQUARES; i++) { if (berry[i] == null) berry[i] = new Array(); var co:uint = i == 0 ? 0 : img.bitmapData.getPixel(i-1,j); berry[i][VSQUARES-j] = co; } } } protected function initWorld():void { world = new Array(); var img:Bitmap = new world_png() as Bitmap; for (var j:int = 0; j < VSQUARES; j++) { for (var i:int = 0; i < HSQUARES; i++) { if (world[i] == null) world[i] = new Array(); world[i][VSQUARES-j] = img.bitmapData.getPixel(i,j); } } } protected function render(e:Event):void { count += STEP; if (tweenMode > 0) tweenCount++; var s:Plane; var a:Number = 2*Math.cos(count*0.05); var b:Number = 1.5*Math.sin(count*0.1); var c:Number = 1.2*Math.cos(count*0.2); //camera.hover(0, viewport.containerSprite.mouseX * 0.02, viewport.containerSprite.mouseY * 0.01); for (var j:int = 0; j < VSQUARES; j++) { for (var i:int = 0; i < HSQUARES; i++) { s = Plane(grid[i][j]); if (s != null) { if (tweenMode == 0) s.material.fillColor = getColour(colourMode, i, j, a, b, c); else { if (tweenCount > 100) { colourMode = tweenMode; tweenMode = 0; tweenCount = 0; } var c1:uint = getColour(colourMode, i, j, a, b, c); var c2:uint = getColour(tweenMode,i,j,a,b,c); s.material.fillColor = ColorUtils.blend(c1,c2,tweenCount/100); } s.z = 20*Math.sin(count+(i+1)*(j+a)*STEP); s.rotationY = s.z*0.05; s.rotationZ = s.z*-0.05; } } } renderer.renderScene(scene, camera, viewport); blit(); } protected function getColour(mode:int, i:int, j:int, a:Number = 0, b:Number = 0, c:Number = 0):uint { var co:uint; if (mode == MODE_CYCLE) { return ( (0x90 + 0x40*Math.sin(count+(-i+1)*(j+a)*STEP)) | ((0x90 + 0x40*Math.cos((count*0.4)+(i+1)*(j+b)*STEP)) <<8) | ((0x90 + 0x40*Math.sin((count*0.6)+(-i+1)*(-j+c)*STEP)) <<16) ); } else if (mode == MODE_BERRY || mode == MODE_WORLD) { co = mode == MODE_BERRY ? berry[i][j] : world[i][j]; return co > 0 ? razor.utils.ColorUtils.brighten(co, 0.3*Math.sin((count*0.6)+(-i+1)*(-j+c)*STEP)) : 0; } else if (mode == MODE_SPARKLY) { if (sparkles == null) sparkles = new Array(); if (sparkles[i] == null) sparkles[i] = new Array(); co = sparkles[i][j]; if (isNaN(co)) co = 0; co = ColorUtils.brighten(co, -0.01); if (co == 0) { var rr:Number = Math.random()*0xa0+0x40; var r:Number = Math.min(rr, Math.random()*0x80); co = rr | (r << 8) | (r << 16); } sparkles[i][j] = co; return co; } return 0; } protected function blit():void { /* Testing a quick depth of field pass.. was abandoned :) */ if (DOF) { bitmapData.lock(); bitmapBuffer.lock(); bitmapBuffer.fillRect(new Rectangle(0,0,bitmapBuffer.width, bitmapBuffer.height), 0); bitmapBuffer.draw(viewport, blitMatrix, null, BlendMode.NORMAL,null, false); var aw:Number = bitmapBuffer.width; var w:Number = aw/(BLUR_STEPS); var h:Number = bitmapBuffer.height; for (var i:int = 0; i < BLUR_STEPS; i++) { var x:Number = w*i; depthFilter.blurX = 4 + i*4; depthFilter.blurY = 4 + i*4; bitmapData.applyFilter(bitmapBuffer, new Rectangle(x,0,aw - w*i, h), new Point(x,0), depthFilter); var b:BitmapData = bitmapData; bitmapData = bitmapBuffer; bitmapBuffer = b; } if (i % 2 == 1) { var bb:BitmapData = bitmapData; bitmapData = bitmapBuffer; bitmap.bitmapData = bb; } bitmapData.unlock(); bitmapBuffer.unlock(); } else { bitmapData.lock(); bitmapData.fillRect(new Rectangle(0,0,bitmapData.width, bitmapData.height), 0); bitmapData.draw(viewport, blitMatrix, null, BlendMode.NORMAL, null, false); bitmapData.unlock(); } } protected function onTimer(e:TimerEvent):void { timer.delay = 12000; tweenCount = 0; tweenMode = colourMode == MODE_WORLD ? MODE_CYCLE : colourMode+1; switch (tweenMode) { default: case MODE_SPARKLY: TweenLite.to(camera, 10, {x: 3150, y: 1950, z: -800, ease: fl.motion.easing.Cubic.easeInOut}); TweenLite.to(camera.target, 10, {x: 2985, y: 1780, ease: fl.motion.easing.Quadratic.easeInOut}); break; case MODE_WORLD: TweenLite.to(camera, 10, {x: 0, y: 1950, z: -3800, ease: fl.motion.easing.Cubic.easeInOut}); TweenLite.to(camera.target, 10, {x: 1985, y: 780, ease: fl.motion.easing.Quadratic.easeInOut}); break; case MODE_CYCLE: TweenLite.to(camera, 10, {x: -3150, y: -1950, z: -700, ease: fl.motion.easing.Cubic.easeInOut}); TweenLite.to(camera.target, 10, {x: -2985, y: -1780, ease: fl.motion.easing.Quadratic.easeInOut}); break; case MODE_BERRY: TweenLite.to(camera, 10, {x: 800, y: -1250, z: -4200, ease: fl.motion.easing.Cubic.easeInOut}); TweenLite.to(camera.target, 10, {x: -1485, y: 1000, ease: fl.motion.easing.Quadratic.easeInOut}); break; } } protected function onClick(e:MouseEvent):void { navigateToURL(new URLRequest("/blog/"), "_self"); } protected function onResize(e:Event):void { } } }