Carousel 0.3 - yahoo image search api
/**
* Copyright jozefchutka ( http://wonderfl.net/user/jozefchutka )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/wIec
*/
package
{
import __AS3__.vec.Vector;
import caurina.transitions.Tweener;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.net.URLRequest;
import flash.net.navigateToURL;
import flash.utils.Timer;
[SWF(width="465", height="465", frameRate="30", backgroundColor="#FFFFFF")]
public class Carousel extends Sprite
{
public static const ITEMS_ASIDE:uint = 3;
public static const ITEM_WIDTH:Number = 150;
public static const ITEM_HEIGHT:Number = 200;
public static const ITEMS_PREPARED:uint = 3;
public static const ITEMS:uint = ITEMS_ASIDE + ITEMS_PREPARED;
private var itemsWrapper:Sprite = new Sprite();
private var _isMouseIn:Boolean = true;
private var offset:int = 0;
private var rollTimer:Timer = new Timer(2000);
private var zIndexRequired:Boolean = true;
public function Carousel()
{
super();
var leftButton:Btn = new Btn();
leftButton.y = stage.stageHeight;
leftButton.addEventListener(MouseEvent.CLICK, leftClick);
addChild(leftButton);
var rightButton:Btn = new Btn();
rightButton.x = stage.stageWidth;
rightButton.y = stage.stageHeight;
rightButton.addEventListener(MouseEvent.CLICK, rightClick);
addChild(rightButton);
addChild(itemsWrapper);
for(var i:int = -ITEMS; i <= ITEMS; i++)
createItem(i);
addEventListener(Event.ENTER_FRAME, enterFrame);
stage.addEventListener(Event.MOUSE_LEAVE, mouseLeave);
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMove);
rollTimer.addEventListener(TimerEvent.TIMER, rollTimerHandler);
isMouseIn = false;
}
private function set isMouseIn(value:Boolean):void
{
if(value == isMouseIn)
return;
_isMouseIn = value;
if(value)
rollTimer.stop();
else
rollTimer.start();
}
private function get isMouseIn():Boolean
{
return _isMouseIn;
}
private function createItem(position:int):void
{
var item:Item = new Item(ITEM_WIDTH, ITEM_HEIGHT,
position, position - offset);
item.addEventListener(MouseEvent.CLICK, itemClick);
itemsWrapper.addChild(item);
moveItem(item, position, false);
}
private function destroyItem(item:Item):void
{
item.removeEventListener(MouseEvent.CLICK, itemClick);
item.destroy();
}
private function enterFrame(event:Event):void
{
if(zIndexRequired)
zIndex();
zIndexRequired = false;
}
private function mouseLeave(event:Event):void
{
isMouseIn = false;
}
private function mouseMove(event:MouseEvent):void
{
isMouseIn = true;
}
private function leftClick(event:MouseEvent):void
{
moveItems(1);
}
private function rightClick(event:MouseEvent):void
{
moveItems(-1);
}
private function itemClick(event:MouseEvent):void
{
var item:Item = Item(event.currentTarget);
if(!item.position)
navigateToURL(new URLRequest(item.clickUrl), "_blank");
moveItems(-item.position);
}
private function moveItems(n:int):void
{
var list:Vector.<Item> = Item.list.slice();
offset += n;
for each(var item:Item in list)
moveItem(item, item.position + n);
for(var i:uint = 0; i < Math.abs(n); i++)
createItem((ITEMS - i) * (n > 0 ? -1 : 1));
}
private function moveItem(item:Item, position:int,
rotate:Boolean = true):void
{
if(Math.abs(position) > ITEMS)
return destroyItem(item);
item.position = position;
var transform:Transform = new Transform(stage.stageWidth,
stage.stageHeight, ITEMS_ASIDE, position);
if(!rotate)
return Transform.apply(item, transform);
Tweener.addTween(item, {time:1, x:transform.x, y:transform.y,
scaleX:transform.scale, scaleY:transform.scale,
scaleZ:transform.scale, rotationY:transform.rotationY,
transition:"easeOutExpo", onUpdate:rotationUpdate});
}
private function rotationUpdate():void
{
zIndexRequired = true;
}
private function zIndex():void
{
var n:int = itemsWrapper.numChildren;
for (var i:int = 0; i < n; i++)
for (var j:int = i + 1; j < n; j++)
zIndexItems(Item(itemsWrapper.getChildAt(i)),
Item(itemsWrapper.getChildAt(j)));
}
private function zIndexItems(item1:Item, item2:Item):void
{
var scale1:uint = item1.scaleX * 2 + 0.5;
var scale2:uint = item2.scaleX * 2 + 0.5;
var rotation1:int = item1.rotationY;
var rotation2:int = item2.rotationY;
var index1:uint = itemsWrapper.getChildIndex(item1);
var index2:uint = itemsWrapper.getChildIndex(item2);
var scaleProblem:Boolean = (scale1 > scale2 && index1 < index2)
|| (scale1 < scale2 && index1 > index2);
var positionProblem:Boolean =
(rotation1 > 0 && rotation2 > 0 && item1.x < item2.x)
|| (rotation1 < 0 && rotation2 < 0 && item1.x > item2.x);
if(scaleProblem || positionProblem)
itemsWrapper.swapChildren(item1, item2);
}
private function rollTimerHandler(event:TimerEvent):void
{
moveItems(-1);
}
}
}
import __AS3__.vec.Vector;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.GradientType;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.filters.BlurFilter;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.net.URLRequest;
import flash.net.URLVariables;
import flash.net.URLLoader;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.events.IOErrorEvent;
import flash.system.LoaderContext;
import flash.system.ApplicationDomain;
import flash.system.SecurityDomain;
internal class ItemsData extends EventDispatcher
{
private static const SINGLETON_LOCK:Object = {};
private static const _instance:ItemsData = new ItemsData(SINGLETON_LOCK);
private var data:Object = {};
private var requests:Vector.<uint> = new Vector.<uint>();
public function ItemsData(lock:Object)
{
super();
if(lock != SINGLETON_LOCK)
throw new Error("Use ItemsData.instance!");
}
public static function get instance():ItemsData
{
return _instance;
}
public function prepareData(offset:int):void
{
var itemData:Object = getItemData(offset);
if(itemData)
return dispatch(offset, itemData);
var start:uint = calcStart(offset);
if(requests.indexOf(start) != -1)
return;
requests.push(start);
var variables:URLVariables = new URLVariables();
variables.appid = "YahooDemo";
variables.query = "mountains";
variables.results = 1;
variables.start = start + 1;
var request:URLRequest = new URLRequest();
request.url = "http://search.yahooapis.com/ImageSearchService/V1/imageSearch";
request.data = variables;
var loader:URLLoaderDynamic = new URLLoaderDynamic();
loader.offset = offset;
loader.addEventListener(Event.COMPLETE, complete);
loader.load(request);
// HERE COMES IMAGE CALL
// http://search.yahooapis.com/ImageSearchService/V1/imageSearch?appid=YahooDemo&query=Corvette&results=20&start=1000
}
private function complete(event:Event):void
{
var i:uint = 0;
var itemData:Object;
var loader:URLLoaderDynamic = URLLoaderDynamic(event.target);
var offset:int = loader.offset;
var xml:XML = XML(loader.data);
var ns:Namespace = xml.namespace();
default xml namespace = ns;
for each(var result:XML in xml.Result)
{
itemData = {};
itemData.url = result.Thumbnail.Url.toString();
itemData.clickUrl = result.ClickUrl.toString();
data[offset.toString()] = itemData;
dispatch(offset, itemData);
}
default xml namespace = new Namespace("");
}
private function dispatch(offset:int, itemData:Object):void
{
var type:String = ItemsDataEvent.DATA_RECEIVED;
var event:ItemsDataEvent = new ItemsDataEvent(type, false,
false, offset, itemData);
dispatchEvent(event);
}
public function getItemData(offset:int):Object
{
if(data.hasOwnProperty(offset.toString()))
return data[offset.toString()];
return null;
}
public static function calcStart(offset:int):uint
{
var max:uint = 1000;
if(offset < 0)
return calcStart(offset + max);
if(offset > max)
return offset % max;
return offset;
}
}
dynamic class URLLoaderDynamic extends URLLoader
{
}
internal class Item extends Sprite
{
private static const blur:BlurFilter = new BlurFilter(3, 3);
private static const itemsData:ItemsData = ItemsData.instance;
public static var list:Vector.<Item> = new Vector.<Item>();
public var clickUrl:String;
private var _position:int = 0;
private var _offset:int = 0;
private var original:Sprite = new Sprite();
private var reflection:Bitmap = new Bitmap();
private var reflectionShape:Shape = new Shape();
private var loader:Loader = new Loader();
public function Item(width:Number, height:Number, position:int,
offset:int):void
{
mouseEnabled = false;
original.buttonMode = true;
addChild(original);
original.graphics.beginGradientFill(GradientType.RADIAL,
[0xffffff, 0xcccccc],
[1, 1], [0x00, 0xFF]);
original.graphics.drawRect(-width / 2, -height / 2, width, height);
original.graphics.endFill();
createReflection();
addChild(loader);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, complete);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, error);
loader.mouseEnabled = false;
this.position = position;
this.offset = offset;
list.push(this);
}
public function set position(value:int):void
{
_position = value;
}
public function get position():int
{
return _position
}
public function set offset(value:int):void
{
_offset = value;
var type:String = ItemsDataEvent.DATA_RECEIVED;
itemsData.addEventListener(type, dataReceived);
itemsData.prepareData(offset);
}
public function get offset():int
{
return _offset;
}
private function dataReceived(event:ItemsDataEvent):void
{
if(event.offset != offset)
return;
var type:String = ItemsDataEvent.DATA_RECEIVED;
itemsData.removeEventListener(type, dataReceived);
var variables:URLVariables = new URLVariables();
variables.url = event.data.url;
//variables.mime =
var request:URLRequest = new URLRequest("http://www.yoz.sk/proxy.php");
request.data = variables;
loader.load(request, new LoaderContext(true));
clickUrl = event.data.clickUrl;
}
public function createReflection():void
{
removeReflection();
var w:uint = original.width;
var h:uint = original.height;
createReflectionMask(w, h);
var matrix:Matrix = new Matrix();
matrix.translate(w / 2, -h / 2);
matrix.scale(1, -1);
var bitmapData:BitmapData = new BitmapData(w, h, true, 0);
bitmapData.draw(this, matrix);
reflection.bitmapData = bitmapData;
reflection.x = reflectionShape.x;
reflection.y = reflectionShape.y;
reflection.mask = reflectionShape;
reflection.cacheAsBitmap = true;
reflection.filters = [blur];
addChild(reflection);
addChild(reflectionShape);
}
private function complete(event:Event):void
{
var loaderInfo:LoaderInfo = LoaderInfo(event.target);
var loader:Loader = loaderInfo.loader;
var dim:Point = ResizeMath.newDimensions(
new Point(loader.width, loader.height),
new Point(original.width, original.height),
ResizeMath.METHOD_PAN_AND_SCAN);
loader.x = -dim.x / 2;
loader.y = -dim.y / 2;
loader.width = dim.x;
loader.height = dim.y;
loader.mask = original;
createReflection();
}
private function error(event:IOErrorEvent):void
{
}
private function removeReflection():void
{
if(reflection.parent)
removeChild(reflection);
if(reflectionShape.parent)
removeChild(reflectionShape);
}
private function createReflectionMask(w:uint, h:uint):void
{
var shapeMatrix:Matrix = new Matrix();
shapeMatrix.createGradientBox(w, h, Math.PI / 2, 0, 0);
reflectionShape.graphics.beginGradientFill(GradientType.LINEAR,
[0x0, 0x0], [0.3, 0], [0x00, 0xFF], shapeMatrix);
reflectionShape.graphics.drawRect(0, 0, w, h);
reflectionShape.graphics.endFill();
reflectionShape.x = -w / 2;
reflectionShape.y = h / 2;
reflectionShape.cacheAsBitmap = true;
}
public function destroy():void
{
var type:String = ItemsDataEvent.DATA_RECEIVED;
itemsData.removeEventListener(type, dataReceived);
list.splice(list.indexOf(this), 1);
if(parent)
parent.removeChild(this);
}
}
internal class Transform extends Object
{
private var _x:Number = 0;
private var _y:Number = 0;
private var _scale:Number = 1;
private var _rotationY:Number = 0;
private static const SCALES:Object = {
"-3":0.5,
"-2":0.6,
"-1":0.7,
"0":1,
"1":0.7,
"2":0.6,
"3":0.5
};
private static const ROTATIONS:Object = {
"-3":-40,
"-2":-45,
"-1":-50,
"0":0,
"1":50,
"2":45,
"3":40
};
public function Transform(width:Number, height:Number, aside:uint,
position:int):void
{
_scale = calcScale(position);
_rotationY = calcRotationY(position);
_x = calcX(width, aside, position);
_y = height / 2;
}
public function get scale():Number {return _scale};
public function get rotationY():Number {return _rotationY};
public function get x():Number {return _x;}
public function get y():Number {return _y;}
private static function calcScale(position:int):Number
{
if(SCALES.hasOwnProperty(position.toString()))
return SCALES[position.toString()];
return calcScale(position > 0 ? position - 1 : position + 1);
}
private static function calcRotationY(position:int):Number
{
if(ROTATIONS.hasOwnProperty(position.toString()))
return ROTATIONS[position.toString()];
return calcRotationY(position > 0 ? position - 1 : position + 1);
}
private static function calcX(width:Number, aside:uint, position:int):Number
{
var space:Number = width / 2 / (aside + 2);
var p:int = position > 0 ? position + 1 :
position < 0 ? position - 1 : position;
p = position > aside ? p + 2 : position < -aside ? p - 2 : p;
return width / 2 + p * space;
}
public static function apply(item:Item, transform:Transform):void
{
item.x = transform.x;
item.y = transform.y;
item.rotationY = transform.rotationY;
item.scaleX = transform.scale;
item.scaleY = transform.scale;
item.scaleZ = transform.scale;
}
}
internal class ItemsDataEvent extends Event
{
public static const DATA_RECEIVED:String = "ItemsDataEventDATA_RECEIVED";
private var _data:Object;
private var _offset:int;
public function ItemsDataEvent(type:String, bubbles:Boolean=false,
cancelable:Boolean=false, offset:int=0, data:Object=null)
{
super(type, bubbles, cancelable);
_offset = offset;
_data = data;
}
public function get offset():Object
{
return _offset;
}
public function get data():Object
{
return _data;
}
}
internal class Btn extends Sprite
{
public function Btn()
{
buttonMode = true;
graphics.beginFill(Math.random() * 0xffffff);
graphics.drawCircle(0, 0, 20);
graphics.endFill();
}
}
internal class ResizeMath extends Object
{
public static const METHOD_PAN_AND_SCAN:String = "panAndScan";
public static const METHOD_LETTERBOX:String = "letterbox";
public static const METHOD_RAW:String = "raw";
public function ResizeMath()
{
}
public static function fixMethod(method:String):String
{
return (method == METHOD_PAN_AND_SCAN || method == METHOD_LETTERBOX)
? method : METHOD_RAW;
}
public static function newDimensions(origDimensions:Point,
containerDimensions:Point, method:String,
allowEnlarging:Boolean = true):Point
{
var s:Point = scale(origDimensions, containerDimensions, method, allowEnlarging);
return new Point(s.x * origDimensions.x, s.y * origDimensions.y);
}
public static function scale(origDimensions:Point,
containerDimensions:Point, method:String,
allowEnlarging:Boolean = true):Point
{
var sw:Number = containerDimensions.x / origDimensions.x;
var sh:Number = containerDimensions.y / origDimensions.y;
var sx:Number = sw;
var sy:Number = sh;
if(method == METHOD_PAN_AND_SCAN)
sx = sy = Math.max(sw, sh);
else if(method == METHOD_LETTERBOX)
sx = sy = Math.min(sw, sh);
return new Point((sx > 1 && !allowEnlarging) ? 1 : sx,
(sy > 1 && !allowEnlarging) ? 1 : sy);
}
}