forked from: CBC NET - Wonderwall Style
See http://jsdo.it/event/jam/ for details. And be sure to preview in full screen.
/**
* Copyright devon_o ( http://wonderfl.net/user/devon_o )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/fLGr
*/
// forked from Event's CBC NET
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Shape;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.DataEvent;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import net.hires.debug.Stats;
import org.libspark.betweenas3.BetweenAS3;
import org.libspark.betweenas3.easing.Quad;
import org.libspark.betweenas3.tweens.ITween;
/**
* Thanks to makc3d - this http://wonderfl.net/c/kzVu greatly helped me get my around the 'Wonderwall' effect, though I used my own implementation
* @author Devon O.
*/
[SWF(width='465', height='465', backgroundColor='#FFFFFF', frameRate='40')]
public class Main extends Sprite {
private var _grid:Grid;
private var _gridWidth:int;
private var _orgy:int;
private var _scrollRect:Rectangle;
private var _headerRect:Shape;
private var _ty:Number = 0;
private var _loader:Sprite;
private var _loaderFill:Shape;
private var _logo:Loader;
public function Main():void {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(event:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
_scrollRect = new Rectangle(0, 150, 0, stage.stageHeight - 150);
initStage();
initHeader();
initLoader();
loadFeed();
//addChild(new Stats());
}
private function initStage():void {
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.showDefaultContextMenu = false;
stage.addEventListener(Event.RESIZE, onResize);
}
private function initHeader():void {
_headerRect = new Shape();
_headerRect.graphics.beginFill(0x00CCFF);
_headerRect.graphics.drawRect(0, 0, stage.stageWidth, 88);
_headerRect.graphics.endFill();
addChild(_headerRect);
var l:Loader = new Loader();
l.contentLoaderInfo.addEventListener(Event.COMPLETE, onLogoLoad);
l.load(new URLRequest("http://assets.wonderfl.net/images/related_images/8/81/81d9/81d938b82ecdf3b312a66aa83fec539e37462a9bm"), new LoaderContext(true));
}
private function onLogoLoad(event:Event):void {
event.currentTarget.removeEventListener(Event.COMPLETE, onLogoLoad);
_logo = event.currentTarget.loader;
_logo.width = _logo.height = 88;
addChild(_logo);
}
private function initLoader():void {
_loader = new Sprite();
var pat:BitmapData = new BitmapData(3, 3, false, 0xFFFFFF);
pat.setPixel(2, 0, 0x00CCFF);
pat.setPixel(1, 1, 0x00CCFF);
pat.setPixel(0, 2, 0x00CCFF);
_loader.graphics.lineStyle(0, 0x00CCFF);
_loader.graphics.beginBitmapFill(pat);
_loader.graphics.drawRect(0, 0, 100, 9);
_loader.graphics.endFill();
_loaderFill = new Shape();
_loaderFill.graphics.beginFill(0x00CCFF);
_loaderFill.graphics.drawRect(0, 0, 100, 9);
_loaderFill.graphics.endFill();
_loaderFill.scaleX = 0;
_loader.addChild(_loaderFill);
_loader.x = (stage.stageWidth - _loader.width) >> 1;
_loader.y = (stage.stageHeight - _loader.height) >> 1;
addChild(_loader);
}
private function loadFeed():void {
var rssLoader:URLLoader = new URLLoader();
rssLoader.addEventListener(Event.COMPLETE, onRSSLoad);
rssLoader.load(new URLRequest("http://assets.wonderfl.net/static/assets/session5/cbcnet_feed.xml"));
//rssLoader.load(new URLRequest("site.xml"));
}
private function onRSSLoad(event:Event):void {
event.currentTarget.removeEventListener(Event.COMPLETE, onRSSLoad);
var xml:XML = new XML(event.currentTarget.data);
_grid = new Grid(xml);
_grid.addEventListener(Event.COMPLETE, onGridComplete);
_grid.addEventListener(DataEvent.DATA, onProgress);
}
private function onProgress(event:DataEvent):void {
_loaderFill.scaleX = parseFloat(event.data);
}
private function onGridComplete(event:Event):void {
_grid.removeEventListener(Event.COMPLETE, onGridComplete);
_grid.removeEventListener(DataEvent.DATA, onProgress);
removeLoader();
}
private function removeLoader():void {
var t:ITween = BetweenAS3.tween(_loader, { alpha:0 }, null, 1.0, Quad.easeOut);
t.onComplete = onLoaderGone;
t.play();
}
private function onLoaderGone():void {
removeChild(_loader);
_loader = null;
showGrid();
}
private function showGrid():void {
_gridWidth = _grid.width;
_grid.x = (stage.stageWidth - _gridWidth) >> 1;
_grid.y = _orgy = 150;
addChild(_grid);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onFrame);
_grid.addEventListener(MouseEvent.ROLL_OVER, onGridOver);
_grid.addEventListener(MouseEvent.ROLL_OUT, onGridOut);
}
private function onFrame(event:MouseEvent):void {
scrollGrid();
event.updateAfterEvent();
}
private function scrollGrid():void {
if (stage.mouseY > 150) {
var ratio:Number = ((stage.mouseY ) - _scrollRect.y) / (_scrollRect.height);
_grid.y= (_orgy - ((_grid.height + 100) - _scrollRect.height) * ratio) ;
}
//_grid.y += (_ty - _grid.y) / 10;
}
private function onGridOver(event:MouseEvent):void {
_grid.startAnimation();
}
private function onGridOut(event:MouseEvent):void {
_grid.stopAnimation();
}
private function onResize(event:Event):void {
_scrollRect = new Rectangle(0, 150, 0, stage.stageHeight - 150);
if (_grid && contains(_grid)) {
_grid.x = (stage.stageWidth - _gridWidth) >> 1;
}
if (_headerRect) {
_headerRect.width = stage.stageWidth;
}
if (_loader && contains(_loader)) {
_loader.x = (stage.stageWidth - _loader.width) >> 1;
_loader.y = (stage.stageHeight - _loader.height) >> 1;
}
}
}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.Loader;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.DataEvent;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.MouseEvent;
import flash.filters.DropShadowFilter;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.net.navigateToURL;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.text.AntiAliasType;
import flash.text.TextField;
import org.libspark.betweenas3.BetweenAS3;
import org.libspark.betweenas3.easing.Quad;
import org.libspark.betweenas3.tweens.ITween;
class GridItem extends Sprite {
private var _corners:Vector.<CornerPoint>;
private var _graphics:Graphics;
private var _imageData:BitmapData;
private var _di:DistortImage;
private var _link:String;
private var _w:Number;
private var _h:Number;
public function GridItem(w:int = 100, h:int = 100) {
_w = w;
_h = h;
_di = new DistortImage(_w, _h, 4, 4);
var s:Shape = new Shape();
_graphics = s.graphics;
addChild(s);
}
public function setImage(image:BitmapData):void {
_imageData = image;
}
public function setLink(link:String):void {
_link = link;
}
public function setCorners(ul:CornerPoint, ur:CornerPoint, lr:CornerPoint, ll:CornerPoint):void {
_corners = new <CornerPoint>[ul, ur, lr, ll];
}
public function draw():void {
_di.setTransform(_graphics, _imageData, Point(_corners[0]), Point(_corners[1]), Point(_corners[2]), Point(_corners[3]));
}
public function init():void {
addEventListener(MouseEvent.CLICK, onClick);
}
private function onClick(event:MouseEvent):void {
_imageData.colorTransform(_imageData.rect, new ColorTransform(0.1, .70, 1.0));
navigateToURL(new URLRequest(_link), "_blank");
}
}
// rewritten from Sandy3D DistortImage class
// http://www.flashsandy.org/blog/distortimage-20-the-fastest-way-to-freely-distort-image-with-flash-in-actionscript.html
class DistortImage {
private var _yMax:Number;
private var _hsLen:Number;
private var _sMat:Matrix;
private var _hseg:uint;
private var _vsLen:Number;
private var _xMin:Number;
private var _h:Number;
private var _xMax:Number;
private var _tri:Array;
private var _p:Array;
private var _w:Number;
private var _tMat:Matrix;
private var _vseg:uint;
private var _yMin:Number;
public var smoothing:Boolean = true;
public function DistortImage(width:Number, height:Number, vSegments:uint = 2, hSegments:uint = 2):void {
_w = width;
_h = height;
_vseg = vSegments;
_hseg = hSegments;
init();
}
public function setSize(width:Number, height:Number):void {
_w = width;
_h = height;
init();
}
public function setPrecision(hSegments:Number, vSegments:Number):void {
_hseg = hSegments;
_vseg = vSegments;
init();
}
public function get width():Number {
return _w;
}
public function get height():Number {
return _h;
}
public function get hPrecision():uint {
return _hseg;
}
public function get vPrecision():uint {
return _vseg;
}
public function setTransform(graphics:Graphics, bmp:BitmapData, upperLeftPoint:Point, upperRightPoint:Point, lowerRightPoint:Point, lowerLeftPoint:Point):void {
var gx:Number, gy:Number, bx:Number, by:Number;
var dx30:Number = lowerLeftPoint.x - upperLeftPoint.x;
var dy30:Number = lowerLeftPoint.y - upperLeftPoint.y;
var dx21:Number = lowerRightPoint.x - upperRightPoint.x;
var dy21:Number = lowerRightPoint.y - upperRightPoint.y;
var p:Object;
var i:int = _p.length;
while (--i > -1) {
p = _p[i];
gx = (p.x - _xMin) / _w;
gy = (p.y - _yMin) / _h;
bx = upperLeftPoint.x + gy * dx30;
by = upperLeftPoint.y + gy * dy30;
p.sx = bx + gx * (upperRightPoint.x + gy * dx21 - bx);
p.sy = by + gx * (upperRightPoint.y + gy * dy21 - by);
}
render(graphics, bmp);
}
private function init():void {
_p = [];
_tri = [];
var w2:Number = _w * .5;
var h2:Number = _h * .5;
_yMin = 0;
_xMin = 0;
_xMax = _w;
_yMax = _h;
_hsLen = _w / ( _hseg + 1 );
_vsLen = _h / ( _vseg + 1 );
for (var i:int = 0; i < _hseg + 2; i++ ) {
for (var j:int = 0; j < _vseg + 2; j++ ) {
var x:Number = i * _hsLen;
var y:Number = j * _vsLen;
_p.push( { x:x, y:y, sx:x, sy:y } );
}
}
for (i = 0; i < _vseg + 1; i++ ) {
for (j = 0; j < _hseg + 1; j++ ) {
_tri.push([_p[j + i * (_hseg + 2)], _p[j + i * (_hseg + 2) + 1], _p[j + (i + 1) * (_hseg + 2)]]);
_tri.push([_p[j + (i + 1) * (_hseg + 2) + 1], _p[j + (i + 1) * (_hseg + 2)], _p[j + i * (_hseg + 2) + 1]]);
}
}
}
private function render(graphics:Graphics, bmp:BitmapData):void {
graphics.clear();
var x0:Number, y0:Number, x1:Number, y1:Number, x2:Number, y2:Number, x3:Number, y3:Number, x4:Number, y4:Number, x5:Number, y5:Number;
_sMat = new Matrix();
_tMat = new Matrix();
var i:int = _tri.length;
while (--i > -1) {
var tri:Array = _tri[i];
var triPt1:Object = tri[0];
var triPt2:Object = tri[1];
var triPt3:Object = tri[2];
x0 = triPt1.sx;
y0 = triPt1.sy;
x1 = triPt2.sx;
y1 = triPt2.sy;
x2 = triPt3.sx;
y2 = triPt3.sy;
x3 = triPt1.x;
y3 = triPt1.y;
x4 = triPt2.x;
y4 = triPt2.y;
x5 = triPt3.x;
y5 = triPt3.y;
_tMat.tx = x3;
_tMat.ty = y3;
_tMat.a = (x4 - x3) / _w;
_tMat.b = (y4 - y3) / _w;
_tMat.c = (x5 - x3) / _h;
_tMat.d = (y5 - y3) / _h;
_sMat.a = (x1 - x0) / _w;
_sMat.b = (y1 - y0) / _w;
_sMat.c = (x2 - x0) / _h;
_sMat.d = (y2 - y0) / _h;
_sMat.tx = x0;
_sMat.ty = y0;
_tMat.invert();
_tMat.concat(this._sMat);
graphics.beginBitmapFill(bmp, _tMat, false, smoothing);
graphics.moveTo(x0, y0);
graphics.lineTo(x1, y1);
graphics.lineTo(x2, y2);
graphics.endFill();
}
}
}
class Grid extends Sprite {
private var _numColumns:int = 2;
private var _numRows:int;
private var _source:XML;
private var _numCorners:int; // = (num columns + 1) + (num rows * (num columns + 1))
private var _numItems:int;
private var _items:XMLList;
private var _corners:Vector.<CornerPoint>;
private var _gridItems:Vector.<GridItem>;
private var _itemWidth:int = 100;
private var _itemHeight:int = 100;
private var _currentItem:int = 0;
private var _currentCorner:int = 0;
private var _mousePoint:Point = new Point();
private var _imageContainer:Sprite = new Sprite();
public function Grid(xml:XML) {
_source = xml;
hitArea = _imageContainer;
calculateGrid();
}
public function startAnimation():void {
addEventListener(Event.ENTER_FRAME, update);
}
public function stopAnimation():void {
removeEventListener(Event.ENTER_FRAME, update);
reset();
}
private function calculateGrid():void {
_items = _source..item;
_numItems = _items.length();
_numRows = Math.ceil(_numItems / _numColumns);
_numCorners = (_numColumns + 1) + (_numRows * (_numColumns + 1));
_corners = new Vector.<CornerPoint>(_numCorners, true);
_gridItems = new Vector.<GridItem>(_numItems, true);
var cnt:int = 0;
for (var i:int = 0; i < _numRows + 1; i++) {
for (var j:int = 0; j < _numColumns + 1; j++) {
_corners[cnt] = new CornerPoint((j * _itemWidth) + 320, i * _itemHeight);
cnt++;
}
}
initText();
}
private function initText():void {
var cnt:int = 0;
for (var i:int = 0; i < _numItems; i++) {
var tf:TextField = new TextField();
tf.selectable = false;
tf.mouseEnabled = false;
tf.height = 75;
tf.width = 300;
tf.multiline = true;
tf.wordWrap = true;
tf.x = (i % 2 == 0) ? 0 : 540;
tf.y = (i % 2 == 0) ? cnt * 100 : (cnt - 1) * 100;
tf.antiAliasType = AntiAliasType.ADVANCED;
tf.textColor = 0x00CCFF;
tf.text = String(_items[i].description);
tf.cacheAsBitmap = true;
addChild(tf);
if (i % 2 == 0) cnt++;
}
// put image container on top and start loading images
_imageContainer.filters = [new DropShadowFilter(0, 90, 0x000000, 1, 16, 2, 1, 1) ];
addChild(_imageContainer);
loadNextItem();
}
private function loadNextItem():void {
if (_currentItem == _numItems) {
dispatchEvent(new Event(Event.COMPLETE));
} else {
var l:Loader = new Loader();
l.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoaded);
l.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onImageLoadErr);
l.load(new URLRequest(_items[_currentItem].image), new LoaderContext(true));
}
}
private function onImageLoaded(event:Event):void {
event.currentTarget.removeEventListener(Event.COMPLETE, onImageLoaded);
event.currentTarget.removeEventListener(IOErrorEvent.IO_ERROR, onImageLoadErr);
var bmp:Bitmap = event.currentTarget.loader.content;
var mat:Matrix = new Matrix();
mat.scale(100 / bmp.width, 100 / bmp.height);
var dat:BitmapData = new BitmapData(_itemWidth, _itemHeight, false, 0x000000);
dat.draw(bmp, mat, null, null, null, true);
addNextItem(dat);
}
private function addNextItem(dat:BitmapData):void {
if ((_currentCorner + 1) % (_numColumns + 1) == 0) _currentCorner++;
var gi:GridItem = new GridItem(_itemWidth, _itemHeight);
gi.setImage(dat);
gi.setLink(_items[_currentItem].link);
// ul, ur, lr, ll
gi.setCorners(_corners[_currentCorner], _corners[_currentCorner + 1], _corners[(_currentCorner + 1) + (_numColumns + 1)], _corners[_currentCorner + (_numColumns + 1)]);
gi.init();
gi.draw();
_imageContainer.addChild(gi);
_gridItems[_currentItem] = gi;
_currentCorner++;
_currentItem++;
var pct:Number = _currentItem / _numItems;
var e:DataEvent = new DataEvent(DataEvent.DATA);
e.data = String(pct);
dispatchEvent(e);
loadNextItem();
}
private function onImageLoadErr(event:IOErrorEvent):void {
event.currentTarget.removeEventListener(Event.COMPLETE, onImageLoaded);
event.currentTarget.removeEventListener(IOErrorEvent.IO_ERROR, onImageLoadErr);
var dat:BitmapData = new BitmapData(_itemWidth, _itemHeight, false, Math.random() * 0xFFFFFF);
addNextItem(dat);
}
private function update(event:Event):void {
_mousePoint.x = this.mouseX;
_mousePoint.y = this.mouseY;
var i:int = _numCorners;
while (i--) {
_corners[i].update(_mousePoint);
}
i = _numItems;
while (i--) {
_gridItems[i].draw();
}
}
private function reset():void {
var i:int = _numCorners;
addEventListener(Event.ENTER_FRAME, resetPoints);
while (i--) {
var cp:CornerPoint = _corners[i];
var t:ITween = BetweenAS3.tween(cp, { x:cp._orgx, y:cp._orgy }, null, .20, Quad.easeOut);
if (i == 0) t.onComplete = onResetComplete;
t.play();
}
}
private function onResetComplete():void {
removeEventListener(Event.ENTER_FRAME, resetPoints);
}
private function resetPoints(event:Event):void {
var i:int = _numItems;
while (i--) {
_gridItems[i].draw();
}
}
}
class CornerPoint extends Point {
public static const MIN_DIST:Number = 170.0;
private var _vx:Number = 0.0;
private var _vy:Number = 0.0;
private var _dx:Number;
private var _dy:Number;
private var _friction:Number = .40;
public var _orgx:Number;
public var _orgy:Number;
public function CornerPoint(x:Number = 0, y:Number = 0) {
super(x, y);
_orgx = x;
_orgy = y;
}
public function update(mouse:Point):void {
var dx:Number = mouse.x - _orgx;
var dy:Number = mouse.y - _orgy;
var dist:Number = Math.sqrt((dx * dx) + (dy * dy));
if ((dist) < (MIN_DIST)) {
var diff:Number = -dist * ((MIN_DIST) - dist) / (MIN_DIST);
var rad:Number = Math.atan2(mouse.y - _orgy, mouse.x - _orgx);
var diffPoint:Point = Point.polar(diff * 2, rad);
_dx = _orgx + diffPoint.x;
_dy = _orgy + diffPoint.y;
} else {
_dx = _orgx;
_dy = _orgy;
}
_vx += (_dx - x);
_vy += (_dy - y);
_vx *= _friction;
_vy *= _friction;
x += _vx;
y += _vy;
}
}