DAN ZEN EXPO - CODE EXHIBIT -
HIPSTER!
package {
import com.danzen.interfaces.Cropper;
import com.danzen.interfaces.ImageSend;
import com.danzen.interfaces.MobileCamRoll;
import com.danzen.interfaces.Rotator;
import com.danzen.interfaces.TextScroll;
import com.greensock.TweenLite;
import com.greensock.easing.*;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.Loader;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageAspectRatio;
import flash.display.StageOrientation;
import flash.display.StageScaleMode;
import flash.events.*;
import flash.events.TransformGestureEvent;
import flash.filters.*;
import flash.geom.Matrix;
import flash.geom.Rectangle;
import flash.net.URLRequest;
import flash.net.navigateToURL;
import flash.sensors.Accelerometer;
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
import flash.utils.Timer;
public class Hipster extends Sprite {
private var localCheck:Boolean = false;
//private var platform:String = "blackberry";
private var platform:String = "all";
private var photo:MobileCamRoll;
private var assets:MovieClip;
private var sW:Number;
private var sH:Number;
private var scale:Number;
private var rotator:Rotator;
private var cropper:Cropper;
private var rotateTimer:Timer;
private var myData:Data;
// pages
private var splash:MovieClip;
private var home:MovieClip;
private var hunt:MovieClip;
private var post:MovieClip;
private var comment:MovieClip;
private var rotate:MovieClip;
private var crop:MovieClip;
private var tag:MovieClip;
private var full:MovieClip;
private var win:MovieClip;
private var account:MovieClip;
private var search:MovieClip;
private var top:MovieClip;
private var pageList:Array = ["splash", "home", "hunt", "post", "tag", "full", "win", "rotate", "crop", "comment", "account", "search", "top"];
private var picNum:Number = 0;
private var currentPic:Number;
// splash page
private var touchyTweenCheck:Boolean = true;
// tag page
private var imageHeight:Number;
private var urlRoot:String = "http://s3.amazonaws.com/hipstermobi/";
private var nextLoader:Loader;
private var nextPic:MovieClip;
private var nextDirection:String;
private var deepBreath:MovieClip;
private var malfunction:MovieClip;
private var gutter:Number = 40;
private var orientation:String = "portrait";
private var thanksTimer:Timer;
private var infoScroller:TextScroll;
private var rankScroller:TextScroll;
private var messageCheck:Boolean = false;
// full page
private var fullStartScale:Number;
private var fullTimer:Timer;
private var fullDownStartTime:Number;
// account page
private var lastAccount:Object = new Object();
// comment page
private var commentTimer:Timer;
// win page
private var currentWin:Number;
private var winnerTopic:String;
// search page
private var searchCheck:Boolean = false;
private var currentSearch:Number;
private var resultsTimer:Timer;
public function Hipster() {
trace ("hi from Hipster - local: " + localCheck);
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.autoOrients = false;
addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event):void {
initScale();
assets = new Assets();
for (var i:uint=0; i 0) {
comment.image.removeChildAt(0);
}
comment.image.addChild(new Bitmap(bm));
fitImage(comment.image, 0, comment.imageBacking.y, sW/scale, comment.imageBacking.height);
}
//-------------- FULL
if (clip.to == full) {
doFull();
}
}
private function doAd(e:MouseEvent):void {
if (platform == "blackberry") {
navigateToURL(new URLRequest("http://hangy.mobi"));
} else {
navigateToURL(new URLRequest("http://touchy.mobi"));
}
}
private function goSplash(e:MouseEvent):void {
removeChildAt(0);
addChild(splash);
}
////////////////////////// TAG PAGE ////////////////////////////
private function prepareTagPage():void {
Multitouch.inputMode = MultitouchInputMode.GESTURE;
if (tag.contains(tag.info)) {
tag.removeChild(tag.info);
tag.addChild(tag.tags);
}
if (tag.contains(tag.rank)) {tag.removeChild(tag.rank);}
if (tag.contains(tag.rankInfo)) {tag.removeChild(tag.rankInfo);}
if (tag.contains(tag.winBut)) {
tag.removeChild(tag.winBut);
tag.removeChild(tag.headerWin);
tag.addChildAt(tag.tagBut, 0);
tag.addChild(tag.tags);
tag.addChild(tag.header);
}
if (myData.pics.length > 0) {
// check to see if there is a pic loaded
// if not then load the pic and store the current pic
// if there is then just load the tag page
var num:Number = myData.pics[picNum];
if (num != currentPic || tag.image.contains(deepBreath)) {
currentPic = num;
var myLoader:Loader = new Loader();
myData.getInfo(String(currentPic));
myLoader.load(new URLRequest(urlRoot + currentPic + ".jpg"));
myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, tagImageReady);
myLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, tagImageError);
}
} else {
showMalfunction();
}
}
private function doAbout(e:MouseEvent):void {
navigateToURL(new URLRequest("http://hipster.mobi/hipster/about.html"));
}
private function doTag(e:MouseEvent):void {
trace("do Tag");
tag.addChild(tag.tags);
tag.removeChild(tag.info);
}
private function doInfo(e:MouseEvent):void {
trace("do Info");
trace (myData.info.screen);
if (tag.contains(tag.tags)) {
tag.addChild(tag.info);
tag.removeChild(tag.tags);
} else {
tag.addChild(tag.rankInfo);
tag.removeChild(tag.rank);
}
setInfo();
}
private function getInfo(e:Event):void {
setInfo();
}
private function setInfo():void {
var root:MovieClip;
var scroller:TextScroll;
if (tag.contains(tag.info)) {
root = tag.info;
scroller = infoScroller;
} else {
root = tag.rankInfo;
scroller = rankScroller;
}
if (!myData.info.screen) {return;} // I may have deleted an entry while in their memory
root.hunterText.text = myData.info.screen;
root.myText.text = myData.info.comment;
if (root.contains(root.facebook)) {root.removeChild(root.facebook);}
if (root.contains(root.flickr)) {root.removeChild(root.flickr);}
if (root.contains(root.twitter)) {root.removeChild(root.twitter);}
if (myData.info.facebook && myData.info.facebook != "") {
root.addChild(root.facebook);
}
if (myData.info.flickr && myData.info.flickr != "") {
root.addChild(root.flickr);
}
if (myData.info.twitter && myData.info.twitter != "") {
root.addChild(root.twitter);
}
if (myData.info.tags && myData.info.tags.length > 0) {
root.myText.appendText("\n———————————");
for (var i:uint=0; i 0) {
MovieClip(full.image.inner).removeChildAt(0);
}
var newImage:Bitmap = new Bitmap(bmf);
full.image.inner.addChild(newImage);
stage.autoOrients = true;
if (platform == "blackberry") {
accel.addEventListener(AccelerometerEvent.UPDATE, accelUpdate);
}
Multitouch.inputMode = MultitouchInputMode.GESTURE;
// meld is the information screen that disappears after a certain time
full.addChild(full.meld);
full.meld.y = (sH/scale - full.meld.backing.box.height)/2-20;
full.meld.alpha = 1;
TweenLite.to(full.meld, .6, {delay:3.5, alpha:0, ease:Quad.easeInOut, onComplete:meldDone});
// for full we scale a centered outer clip (full.image)
// and we pan a scaled inner clip (full.image.inner)
// so we want to center the outer and initially scale the inner
// make sure the outer clip's scale is reset to start
full.image.scaleX = full.image.scaleY = 1;
fitImage(full.image.inner, 0, 0, sW/scale, sH/scale);
full.image.x = sW / 2 / scale;
full.image.y = sH / 2 / scale;
full.image.inner.x = -full.image.inner.width/2;
full.image.inner.y = -full.image.inner.height/2;
}
private var lastOrientation:String = "vertical";
private var orientTimer:Timer;
private var orientCheck:Boolean = true;
private function accelUpdate(e:AccelerometerEvent):void {
if (orientation == "portrait") {
if( e.accelerationX > 0.5 || e.accelerationX < -0.5 ) {
orientation = "landscape";
} else if( e.accelerationY > 0.5 || e.accelerationY < -0.5 ) {
orientation = "portrait";
}
} else {
if( e.accelerationX > 0.5 || e.accelerationX < -0.5 ) {
orientation = "portrait";
} else if( e.accelerationY > 0.5 || e.accelerationY < -0.5 ) {
orientation = "landscape";
}
}
if (lastOrientation == orientation) {return;}
if (!orientCheck) {return;}
orientCheck = false;
orientTimer.reset();
orientTimer.start();
lastOrientation = orientation;
if (orientation == "landscape") {
trace ("landscape");
stage.setAspectRatio(StageAspectRatio.LANDSCAPE);
landscapeView();
} else {
trace ("portrait");
stage.setAspectRatio(StageAspectRatio.PORTRAIT);
portraitView();
}
}
private function setOrientCheck(e:TimerEvent):void {
orientCheck = true;
}
private function doZoom(e:TransformGestureEvent):void {
// multitouch method for full screen pic zoom (on tag page)
if (e.phase == GesturePhase.BEGIN) {
full.image.removeEventListener(MouseEvent.MOUSE_DOWN, doDown);
full.image.stopDrag();
}
var newScale:Number = (e.scaleX + e.scaleY) / 2;
e.target.scaleX *= newScale;
e.target.scaleY *= newScale;
e.target.scaleX = Math.max(e.target.scaleX, 1);
e.target.scaleY = Math.max(e.target.scaleY, 1);
e.target.scaleX = Math.min(e.target.scaleX, 6);
e.target.scaleY = Math.min(e.target.scaleY, 6);
if(e.phase == GesturePhase.END) {
full.image.addEventListener(MouseEvent.MOUSE_DOWN, doDown);
}
}
private function doDown(e:MouseEvent):void {
var d:Date = new Date();
fullDownStartTime = d.getTime();
stage.addEventListener(MouseEvent.MOUSE_UP, doUp);
stage.addEventListener(MouseEvent.MOUSE_MOVE, doMove);
full.image.offsetX = full.image.mouseX - full.image.inner.x;
full.image.offsetY = full.image.mouseY - full.image.inner.y;
}
private function doMove(e:MouseEvent):void {
full.image.inner.x = full.image.mouseX - full.image.offsetX;
full.image.inner.y = full.image.mouseY - full.image.offsetY;
// don't let any of the four edges go past center which is 0,0
full.image.inner.x = Math.min(full.image.inner.x, 0);
full.image.inner.y = Math.min(full.image.inner.y, 0);
full.image.inner.x = Math.max(full.image.inner.x, -full.image.inner.width);
full.image.inner.y = Math.max(full.image.inner.y, -full.image.inner.height);
}
private function doUp(e:MouseEvent):void {
stage.removeEventListener(MouseEvent.MOUSE_UP, doUp);
stage.removeEventListener(MouseEvent.MOUSE_MOVE, doMove);
full.image.stopDrag();
}
private function fullResize(e:MouseEvent):void {
var d:Date = new Date();
if (d.getTime() - fullDownStartTime > 300) {return;}
fullTimer.start();
}
private function fullExit(e:MouseEvent):void {
fullTimer.stop();
removeChildAt(0);
addChild(tag);
stage.autoOrients = false;
if (platform == "blackberry") {
accel.removeEventListener(AccelerometerEvent.UPDATE, accelUpdate);
stage.setAspectRatio(StageAspectRatio.PORTRAIT);
} else {
stage.setOrientation(StageOrientation.DEFAULT);
}
Multitouch.inputMode = MultitouchInputMode.GESTURE;
}
private function singleClickHandler(e:TimerEvent):void {
full.image.scaleX = full.image.scaleY = 1;
if (orientation == "portrait") {
fitImage(full.image.inner, 0, 0, sW/scale, sH/scale);
portraitView();
} else {
fitImage(full.image.inner, 0, 0, sH/scale, sW/scale);
landscapeView();
}
full.image.inner.x = -full.image.inner.width/2;
full.image.inner.y = -full.image.inner.height/2;
}
private function doOrientation(e:StageOrientationEvent):void {
if (platform == "blackberry") {
/*
if (stage.fullScreenWidth > 0) {
if (stage.fullScreenWidth > stage.fullScreenHeight) {
trace ("orient horizontal");
orientation = "horizontal";
landscapeView();
} else {
trace ("orient vertical");
orientation = "vertical";
portraitView();
}
} else {
if (stage.stageWidth > stage.stageHeight) {
orientation = "horizontal";
landscapeView();
} else {
orientation = "vertical";
portraitView();
}
}
*/
} else {
switch (e.afterOrientation) {
case StageOrientation.DEFAULT:
orientation = "portrait";
portraitView();
break;
case StageOrientation.ROTATED_RIGHT:
orientation = "landscape";
landscapeView();
break;
case StageOrientation.ROTATED_LEFT:
orientation = "landscape";
landscapeView();
break;
case StageOrientation.UPSIDE_DOWN:
orientation = "portrait";
portraitView();
break;
}
}
}
private function portraitView():void {
full.image.x = sW/2/scale;
full.image.y = sH/2/scale;
}
private function landscapeView():void {
full.image.x = sH/2/scale;
full.image.y = sW/2/scale;
}
//////////////////// SWIPING //////////////////
private var swipeCheck:Boolean = true;
private var swipeTimer:Timer;
private function nextImageSwipe(e:TransformGestureEvent):void {
trace ("swipe");
if (myData.pics.length == 0) {return;}
if (!swipeCheck) {return;}
if (e.offsetX < 0) { // swipe left (forward)
getNextImage();
} else { // right (back)
getPrevImage();
}
swipeCheck = false;
swipeTimer.reset();
swipeTimer.start();
}
private function setSwipeCheck(e:TimerEvent):void {
swipeCheck = true;
}
private function getNextImage():void {
picNum++;
if (picNum >= myData.pics.length) {picNum = 0;}
deepBreath.arrow.rotation = 180;
if (tag.contains(tag.rank) || tag.contains(tag.rankInfo)) {
currentWin++;
if (currentWin >= myData.winners.length) {
currentWin = 0;
}
tag.rank.myText.text = String(currentWin+1);
picNum = myData.picNums[myData.winners[currentWin]];
}
if (searchCheck) {
currentSearch++;
if (currentSearch >= myData.search.length) {
currentSearch = 0;
}
picNum = myData.picNums[myData.search[currentSearch]];
}
getImage();
}
private function getPrevImage():void {
picNum--;
if (picNum < 0) {picNum = myData.pics.length-1;}
deepBreath.arrow.rotation = 0;
if (tag.contains(tag.rank) || tag.contains(tag.rankInfo)) {
currentWin--;
if (currentWin < 0) {
currentWin = myData.winners.length-1;
}
tag.rank.myText.text = String(currentWin+1);
picNum = myData.picNums[myData.winners[currentWin]];
}
if (searchCheck) {
currentSearch--;
if (currentSearch < 0) {
currentSearch = myData.search.length-1;
}
picNum = myData.picNums[myData.search[currentSearch]];
}
getImage();
}
private function getPics(e:Event):void {
trace ("----------------------------"+myData.pics[1]);
}
private function getImage():void {
tag.info.hunterText.text = "...";
tag.info.myText.text = "...";
tag.image.removeChildAt(0);
tag.image.addChild(deepBreath);
deepBreath.arrow.visible = true;
fitImage(tag.image, gutter/2/scale, tag.imageBacking.y, (sW-gutter)/scale, tag.imageBacking.height);
currentPic = myData.pics[picNum];
myData.getInfo(String(currentPic));
nextLoader.load(new URLRequest(urlRoot + currentPic + ".jpg"));
}
private function nextImage(e:MouseEvent):void {
trace ("nextImage");
if (myData.pics.length == 0) {return;}
getNextImage();
}
private function nextWinImage(e:MouseEvent):void {
if (myData.pics.length == 0) {return;}
getNextImage();
}
private function prevWinImage(e:MouseEvent):void {
if (myData.pics.length == 0) {return;}
getPrevImage();
}
private function nextImageReady(e:Event):void {
tag.image.removeChildAt(0);
deepBreath.arrow.visible = false;
var bmd:BitmapData = new BitmapData(nextLoader.content.width, nextLoader.content.height, false, 0);
bmd.draw(nextLoader.content);
tag.image.addChild(new Bitmap(bmd));
fitImage(tag.image, gutter/2/scale, tag.imageBacking.y, (sW-gutter)/scale, tag.imageBacking.height);
}
/*
private var swipeDownStartTime:Number;
private function swiperDown(e:MouseEvent):void {
// set timer to differentiate swipe and press on pic
var d:Date = new Date();
swipeDownStartTime = d.getTime();
}
private function gotoFull(e:MouseEvent):void {
// called from clicking on image (swiper)
// will conflict with swipe unless manage
var d:Date = new Date();
if (d.getTime() - swipeDownStartTime > 300) {return;}
stage.autoOrients = false;
stage.setOrientation(StageOrientation.DEFAULT);
removeChildAt(0);
addChildAt(full, 0);
doFull();
}
*/
/////////////////////////// SEARCH ///////////////////////////////////
private function showSearch():void {
addChild(search);
}
private function doSearchCancel(e:MouseEvent):void {
removeChild(search);
}
private function doTopCancel(e:MouseEvent):void {
removeChild(top);
}
private function doSearch(e:MouseEvent):void {
myData.doSearch(search.pane.screenText.text, search.pane.tagText.text, search.pane.commentText.text);
}
private function doNewest(e:MouseEvent):void {
myData.doSearch("", "newest", "");
}
private function doOldest(e:MouseEvent):void {
myData.doSearch("", "oldest", "");
}
private function showResults():void {
search.removeChild(search.pane);
search.results.addChild(search.results.target);
search.results.addChild(search.results.targets);
if (myData.search.length == 1) {
search.results.removeChild(search.results.targets);
} else {
search.results.removeChild(search.results.target);
}
search.results.resultText.text = String(myData.search.length);
search.addChild(search.results);
resultsTimer.start();
}
private function doResultTimer(e:TimerEvent):void {
resultsTimer.reset();
if (contains(search)) {
removeChild(search);
}
if (contains(top)) {
removeChild(top);
}
if (search.contains(search.results)) {
search.removeChild(search.results);
search.addChild(search.pane);
}
}
private function getSearch(e:Event):void {
showResults();
if (myData.search.length <= 0) {return;}
searchCheck = true;
tag.header.removeChild(tag.header.searchBut);
tag.header.addChild(tag.header.clearBut);
tag.image.removeChildAt(0);
tag.image.addChild(deepBreath);
fitImage(tag.image, gutter/2/scale, tag.imageBacking.y, (sW-gutter)/scale, tag.imageBacking.height);
currentSearch = 0;
picNum = myData.picNums[myData.search[currentSearch]];
prepareTagPage();
}
private function doSearchClear(e:MouseEvent):void {
tag.header.removeChild(tag.header.clearBut);
tag.header.addChild(tag.header.searchBut);
searchCheck = false;
}
private function searchOff():void {
searchCheck = false;
if (tag.header.contains(tag.header.clearBut)) {
tag.header.removeChild(tag.header.clearBut);
tag.header.addChild(tag.header.searchBut);
}
}
////////////////////// ACCOUNT ///////////////////////////
private function showAccount():void {
addChild(account);
lastAccount.screen = account.pane.screenText.text;
lastAccount.facebook = account.pane.facebookText.text;
lastAccount.twitter = account.pane.twitterText.text;
}
private function doAccountCancel(e:MouseEvent):void {
account.pane.screenText.text = lastAccount.screen;
account.pane.facebookText.text = lastAccount.facebook;
account.pane.twitterText.text = lastAccount.twitter;
removeChild(account);
}
private function doAccountSave(e:MouseEvent):void {
lastAccount.screen = account.pane.screenText.text;
lastAccount.facebook = account.pane.facebookText.text;
lastAccount.twitter = account.pane.twitterText.text;
removeChild(account);
if (getChildAt(0) == post && lastAccount.screen != "") {
post.addChild(post.processing);
photo.getPhoto();
}
if (getChildAt(0) == comment && lastAccount.screen != "") {
uploadImage(null);
}
}
///////////////////////// UPLOAD //////////////////////////////
private function uploadImage(e:MouseEvent):void {
if (lastAccount.screen == undefined || lastAccount.screen == "") {
showAccount();
return;
}
if (comment.myText.text == "" || comment.myText.text == "Doing? Saying? Thinking?" || comment.myText.text == "Please type a few words...") {
comment.myText.text = "Please type a few words...";
return;
}
comment.waitMessage.alpha = 1;
// delay to make sure message activates before upload processes
// there is no animation, etc. as image is uploading - we are frozen
commentTimer.reset();
commentTimer.start();
}
private function uploadImage2(e:TimerEvent):void {
var now:Date = new Date();
var imageID:String = now.getTime() + "" + Math.round(Math.random()*1000);
// create a jpg from cropper bitmapData and send to php which will write to Amazon
if (!localCheck) {
new ImageSend(cropper.getBitmapData(), "http://danzen.com/hipster/image.php?id="+imageID);
}
// write URL and info to database
var obj:Object = {};
obj.pid = imageID;
obj.screen = account.pane.screenText.text;
account.pane.facebookText.text = account.pane.facebookText.text.replace(/^(.*)facebook\.com\//i, "");
account.pane.twitterText.text = account.pane.twitterText.text.replace(/^(.*)twitter\.com\//i, "");
obj.facebook = account.pane.facebookText.text;
obj.twitter = account.pane.twitterText.text;
obj.comment = comment.myText.text;
if (!localCheck) {
myData.newPic(obj);
}
removeChildAt(0);
// set the tag picture to the cropped pic
tag.image.removeChildAt(0);
tag.image.addChild(new Bitmap(cropper.getBitmapData()));
fitImage(tag.image, gutter/2/scale, tag.imageBacking.y, (sW-gutter)/scale, tag.imageBacking.height);
// insert new picture ID into pics array
myData.pics.splice(picNum,0,imageID);
myData.setPicNums();
currentPic = Number(imageID);
prepareTagPage();
// new stuff
if (messageCheck == false) {
tag.addChild(tag.message);
} else if (tag.contains(tag.message)) {
tag.removeChild(tag.message);
}
searchOff();
addChild(tag);
myData.info = {screen:obj.screen, facebook:obj.facebook, twitter:obj.twitter, comment:obj.comment};
setInfo();
tag.setChildIndex(tag.swiper, tag.numChildren-1);
trace ("input mode = " + Multitouch.inputMode);
if (!tag.swiper.hasEventListener(TransformGestureEvent.GESTURE_SWIPE)) {
tag.swiper.removeEventListener(TransformGestureEvent.GESTURE_SWIPE, nextImageSwipe);
}
tag.swiper.addEventListener(TransformGestureEvent.GESTURE_SWIPE, nextImageSwipe);
}
private function photoCancel(e:Event):void {
trace("canceled photo");
// just stay on upload page
post.removeChild(post.processing);
}
private function photoLoaded(e:Event):void {
post.removeChild(post.processing);
if (e.target.error != "success") {
// error getting photo
trace ("photo not accepted");
showMalfunction();
return;
}
removeChildAt(0);
// take out placeholder inner image and add Bitmap from cam roll bitmapData
rotate.image.removeChildAt(0);
rotate.image.addChild(new Bitmap(e.target.bitmapData as BitmapData));
fitImage(rotate.image, 0, rotate.imageBacking.y, sW/scale, rotate.imageBacking.height);
setRotator();
addChild(rotate);
}
private function doCropBack(e:MouseEvent):void {
// unique handler to avoid getting new cam roll picture
removeChildAt(0);
addChild(rotate);
}
private function doCommentBack(e:MouseEvent):void {
// unique handler to avoid resetting the crop position
removeChildAt(0);
addChild(crop);
}
private function setRotator():void {
if (rotator) {
rotator.dispose();
rotator = null;
}
// Rotator adds an event handler to rotation button
// then handles rotating the image making a new bitmapData property each time
// in the end, the bitmapData property is used to feed the crop screen image
rotator = new Rotator(rotate.image.getChildAt(0), rotate.rotateBut);
rotator.addEventListener(Rotator.ROTATE, doRotate);
}
private function doRotate(e:Event):void {
// center pic again
fitImage(rotate.image, 0, rotate.imageBacking.y, sW/scale, rotate.imageBacking.height);
}
private function setCropper():void {
if (cropper) {
crop.removeChild(cropper);
cropper.dispose();
cropper = null;
}
// Cropper adds multitouch events to the crop handles
// it also dynamically draws the crop rectangle joining the handles
// and it provides a method to get the bitmapData of the pic in the crop rectangle
// this bitmapData is then used to draw the pic in the comment page
if (platform == "blackberry") {
cropper = new Cropper(crop.image, crop.cropLeft, crop.cropRight, false);
} else {
cropper = new Cropper(crop.image, crop.cropLeft, crop.cropRight);
}
crop.addChild(cropper);
}
private function meldDone():void {
// method to remove the information screen on the fullscreen page once the tween is done
if (full.contains(full.meld)) {
full.removeChild(full.meld);
}
}
private function setComment(e:FocusEvent):void {
comment.myText.text = "";
comment.myText.removeEventListener(FocusEvent.FOCUS_IN, setComment);
}
///////////////////////// WINNERS ///////////////////////////////////////////////
private function doWin(e:MouseEvent):void {
winnerTopic = e.target.name.substr(2,e.target.name.length-2);
myData.getWinners(winnerTopic);
}
private function getWinners(e:Event):void {
var topic:String = (winnerTopic.match(/0s/)) ? winnerTopic : winnerTopic.toUpperCase();
top.results.addChild(top.results.target);
top.results.addChild(top.results.targets);
if (myData.winners.length == 1) {
top.results.removeChild(top.results.targets);
} else {
top.results.removeChild(top.results.target);
}
top.results.resultText.text = String(myData.winners.length);
resultsTimer.start();
if (myData.winners.length <= 0) {
// pop no-tag-yet message
addChild(top);
return;
}
tag.image.removeChildAt(0);
tag.image.addChild(deepBreath);
fitImage(tag.image, gutter/2/scale, tag.imageBacking.y, (sW-gutter)/scale, tag.imageBacking.height);
currentWin = 0;
picNum = myData.picNums[myData.winners[currentWin]];
removeChild(win);
searchOff();
prepareTagPage();
tag.addChildAt(tag.winBut, 0);
tag.addChild(tag.rank);
tag.addChild(tag.headerWin);
tag.rank.tagText.text = topic;
tag.rank.myText.text = String(currentWin+1);
if (tag.contains(tag.info)) {tag.removeChild(tag.info);}
if (tag.contains(tag.tags)) {tag.removeChild(tag.tags);}
if (tag.contains(tag.tagBut)) {tag.removeChild(tag.tagBut);}
addChild(tag);
addChild(top);
}
private function doRank(e:MouseEvent):void {
trace("do Rank");
tag.addChild(tag.rank);
tag.removeChild(tag.rankInfo);
}
///////////////////////////////// SCALE FUNCTIONS /////////////////////////////////////
private function adjustForResolutions():void {
// for this app, we are locked on vertical (portrait)
// all pages are anchored to the top with enough background to handle iPod 5 (narrow)
// SPLASH PAGE - Button
// position splash button at bottom
// this button is inside a scaled clip
// convert it to the stage scale by x scale - make desired change
// convert the answer back to the local scale by / scale
splash.gogoBut.y = (sH - splash.gogoBut.height/2 * scale * 1.5) / scale;
// TAG PAGE - Tags
// on tag page need to put tags at bottom of page and then set picture height
// tags is the pannel of tags - with the registration point set at the bottom
var tagsStartY:Number = tag.tags.y;
tag.tags.y = sH / scale;
tag.info.y = sH / scale;
tag.tagTool.y = sH / scale;
tag.rankInfo.y = sH / scale;
tag.rank.y = sH / scale;
// ipad
var iPadScale:Number = 1;
if (sW / sH > .7 && sW / sH < .8 && sW > 700) {
iPadScale = .75;
}
var startPadH:Number = tag.tags.height;
tag.tags.scaleX = tag.tags.scaleY = tag.tags.scaleX * iPadScale;
tag.tags.x = (1-iPadScale) * sW / scale / 2;
tag.info.scaleX = tag.info.scaleY = tag.info.scaleX * iPadScale;
tag.info.x = (1-iPadScale) * sW / scale / 2;
tag.rankInfo.scaleX = tag.rankInfo.scaleY = tag.rankInfo.scaleX * iPadScale;
tag.rankInfo.x = (1-iPadScale) * sW / scale / 2;
tag.rank.scaleX = tag.rank.scaleY = tag.rank.scaleX * iPadScale;
tag.rank.x = (1-iPadScale) * sW / scale / 2;
var iPadAdded:Number = (startPadH - tag.tags.height) / scale / 1.1;
var dif:Number = tagsStartY - tag.tags.y;
imageHeight = tag.imageBacking.height - dif + iPadAdded;
tag.imageBacking.height = imageHeight;
fitImage(tag.image, gutter/2/scale, tag.imageBacking.y, (sW-gutter)/scale, tag.imageBacking.height);
// HUNT PAGE - ergone
if ((hunt.ergone.y + hunt.ergone.height + 20) * scale > sH) {
hunt.removeChild(hunt.ergone);
}
// ROTATE PAGE - image (not needed on mobile)
fitImage(rotate.image, 0, rotate.imageBacking.y, sW/scale, rotate.imageBacking.height);
// MENU PAGE - Ad
var adSpace:Number = sH / scale - (home.tagBut.y + home.tagBut.height);
if (home.ad.contains(home.ad.big)) {
home.ad.removeChild(home.ad.big);
}
if (home.ad.contains(home.ad.small)) {
home.ad.removeChild(home.ad.small);
}
if (home.ad.contains(home.ad.bigHangy)) {
home.ad.removeChild(home.ad.bigHangy);
}
if (home.ad.contains(home.ad.smallHangy)) {
home.ad.removeChild(home.ad.smallHangy);
}
if (home.ad.big.height > adSpace * .8) {
if (platform == "blackberry") {
home.ad.addChild(home.ad.smallHangy);
} else {
home.ad.addChild(home.ad.small);
}
} else {
if (platform == "blackberry") {
home.ad.addChild(home.ad.bigHangy);
} else {
home.ad.addChild(home.ad.big);
}
}
fitImage(home.ad, 0, 0, sW / scale *.8, adSpace * .8);
home.ad.y = sH / scale - adSpace / 2;
home.ad.x = sW / scale;
/*
// MENU PAGE - Ad
if ((home.ad.y + home.ad.big.y + home.ad.big.height) * scale > sH) {
home.ad.removeChild(home.ad.big);
trace ("here2");
} else {
home.ad.removeChild(home.ad.small);
return;
}
if ((home.ad.y+20) * scale > sH) {
home.ad.removeChild(home.ad.small);
} else {
var startH:Number = home.ad.small.height;
var startW:Number = home.ad.small.width;
var scaleAd:Number = (sH - (home.ad.y+20) * scale) / scale / startH;
home.ad.scaleX = home.ad.scaleY = scaleAd;
if (home.ad.width > sW / scale - 40) {
home.ad.scaleX = home.ad.scaleY = 1;
scaleAd = home.ad.width / (sW / scale - 40);
home.ad.scaleX = home.ad.scaleY = scaleAd;
}
if (platform == "apple") {
home.ad.y += (sH - home.ad.y*scale) / 2.5;
if (home.ad.y + home.ad.height > sH / scale) {
home.ad.y = - home.ad.height + sH / scale - 5;
}
} else {
home.ad.y += (sH - home.ad.y*scale) / 2.5;
if (home.ad.y + home.ad.height > sH / scale) {
home.ad.y = - home.ad.height + sH / scale - 5;
}
}
home.ad.x = sW / scale - home.ad.width - 20;
}
*/
}
private function fitImage(img:MovieClip, minX:Number, minY:Number, maxWidth:Number, maxHeight:Number):void {
// generic function to fit a clip in a rectangle and center it
img.scaleX = img.scaleY = 1;
var imageScale:Number = maxHeight / img.height;
img.scaleX = img.scaleY = imageScale;
if (img.width > maxWidth) {
img.scaleX = img.scaleY = 1;
imageScale = maxWidth / img.width;
img.scaleX = img.scaleY = imageScale;
img.x = minX;
img.y = minY + (maxHeight - img.height) / 2;
} else {
img.x = minX + (maxWidth - img.width) / 2;
img.y = minY;
}
}
private function initScale():void {
if (stage.fullScreenWidth > 0) {
sW = stage.fullScreenWidth;
sH = stage.fullScreenHeight;
} else {
sW = stage.stageWidth;
sH = stage.stageHeight;
}
if (sW > sH) {
var temp:Number = sW;
sW = sH; sH = temp;
}
scale = sW / 640; // hardcoded due to dropshadow messing up width
}
private function setScale(w:MovieClip):void {
w.scaleX = w.scaleY = scale;
}
}
}
package com.danzen.interfaces {
import flash.display.BitmapData;
import flash.display.MovieClip;
import flash.events.*;
import flash.geom.Matrix;
public class Cropper extends MovieClip {
private var image:MovieClip;
private var leftHandle:MovieClip;
private var rightHandle:MovieClip;
private var startGutter:Number = 40;
private var downCheck:Boolean = false;
private var dragLeftCheck:Boolean = false;
private var dragRightCheck:Boolean = false;
private var scale:Number;
private var touches:Object = new Object();
private var multitouch:Boolean;
public function Cropper(theImage:MovieClip, theLeftHandle:MovieClip, theRightHandle:MovieClip, theMultitouch:Boolean=true) {
trace ("hi from Cropper");
image = theImage;
scale = image.scaleX;
leftHandle = theLeftHandle; rightHandle = theRightHandle;
leftHandle.mouseChildren = false;
rightHandle.mouseChildren = false;
leftHandle.x = image.x + startGutter; leftHandle.y = image.y + startGutter;
rightHandle.x = image.x + image.width - startGutter; rightHandle.y = image.y + image.height - startGutter;
multitouch = theMultitouch;
drawCropRect();
if (multitouch) {
leftHandle.addEventListener(TouchEvent.TOUCH_BEGIN, doDown);
rightHandle.addEventListener(TouchEvent.TOUCH_BEGIN, doDown);
} else {
leftHandle.addEventListener(MouseEvent.MOUSE_DOWN, doDown2);
rightHandle.addEventListener(MouseEvent.MOUSE_DOWN, doDown2);
}
leftHandle.buttonMode = rightHandle.buttonMode = true;
}
// single touch
private function doDown2(e:MouseEvent):void {
if (!downCheck) {
image.stage.addEventListener(MouseEvent.MOUSE_MOVE, setBounds2);
image.stage.addEventListener(MouseEvent.MOUSE_UP, doUp2);
}
if (e.target == leftHandle) {
dragLeftCheck = true;
}
if (e.target == rightHandle) {
dragRightCheck = true;
}
e.target.offsetX = image.parent.mouseX - e.target.x;
e.target.offsetY = image.parent.mouseY - e.target.y;
}
private function doUp2(e:MouseEvent):void {
image.stage.removeEventListener(MouseEvent.MOUSE_MOVE, setBounds2);
image.stage.removeEventListener(MouseEvent.MOUSE_UP, doUp2);
downCheck = false;
dragLeftCheck = false;
dragRightCheck = false;
}
private function setBounds2(e:Event):void {
if (dragLeftCheck) {
leftHandle.x = image.parent.mouseX - leftHandle.offsetX;
leftHandle.y = image.parent.mouseY - leftHandle.offsetY;
}
bounds(leftHandle);
if (dragRightCheck) {
rightHandle.x = image.parent.mouseX - rightHandle.offsetX;
rightHandle.y = image.parent.mouseY - rightHandle.offsetY;
}
bounds(rightHandle);
drawCropRect();
}
// multitouch
private function doDown(e:TouchEvent):void {
if (!downCheck) {
downCheck = true;
image.stage.addEventListener(TouchEvent.TOUCH_MOVE, setBounds);
image.stage.addEventListener(TouchEvent.TOUCH_END, doUp);
}
touches[e.touchPointID] = e.target;
e.target.offsetX = e.stageX - e.target.x;
e.target.offsetY = e.stageY - e.target.y;
}
private function doUp(e:TouchEvent):void {
delete touches[e.touchPointID];
for each (var prop:Object in touches) {var full:Boolean=true; break;}
if (!full) {
image.stage.removeEventListener(TouchEvent.TOUCH_MOVE, setBounds);
image.stage.removeEventListener(TouchEvent.TOUCH_END, doUp);
downCheck = false;
}
}
private function setBounds(e:TouchEvent):void {
var t:MovieClip = MovieClip(touches[e.touchPointID]);
t.x = e.stageX - t.offsetX;
t.y = e.stageY - t.offsetY;
bounds(t);
drawCropRect();
}
private function drawCropRect():void {
graphics.clear();
graphics.lineStyle(4,0x000000,1,false);
graphics.drawRect(leftHandle.x, leftHandle.y, rightHandle.x - leftHandle.x, rightHandle.y - leftHandle.y);
graphics.lineStyle(4,0xfffffff,1,false);
graphics.drawRect(leftHandle.x+4, leftHandle.y+4, rightHandle.x - leftHandle.x - 8, rightHandle.y - leftHandle.y - 8);
}
private function bounds(w:MovieClip):void {
if (w.x < image.x) {
w.x = image.x;
}
if (w.y < image.y) {
w.y = image.y;
}
if (w.x > image.x + image.width) {
w.x = image.x + image.width;
}
if (w.y > image.y + image.height) {
w.y = image.y + image.height;
}
if (w == leftHandle) {
if (w.x + leftHandle.width * 1.5 > rightHandle.x) {
w.x = rightHandle.x - leftHandle.width * 1.5;
}
if (w.y + leftHandle.height * 1.5 > rightHandle.y) {
w.y = rightHandle.y - leftHandle.height * 1.5;
}
} else if (w == rightHandle) {
if (w.x - rightHandle.width * 1.5 < leftHandle.x) {
w.x = leftHandle.x + rightHandle.width * 1.5;
}
if (w.y - rightHandle.height * 1.5 < leftHandle.y) {
w.y = leftHandle.y + rightHandle.height * 1.5;
}
}
}
public function getBitmapData():BitmapData {
var bmData:BitmapData = new BitmapData((rightHandle.x - leftHandle.x)/scale, (rightHandle.y - leftHandle.y)/scale, false);
var matrix:Matrix = new Matrix();
matrix.translate((image.x-leftHandle.x)/scale, (image.y-leftHandle.y)/scale);
bmData.draw(image, matrix);
return bmData;
}
public function dispose():void {
leftHandle.removeEventListener(TouchEvent.TOUCH_BEGIN, doDown);
rightHandle.removeEventListener(TouchEvent.TOUCH_BEGIN, doDown);
if (downCheck) {
image.stage.removeEventListener(TouchEvent.TOUCH_MOVE, setBounds);
image.stage.removeEventListener(TouchEvent.TOUCH_END, doUp);
}
}
}
}
package com.danzen.interfaces {
import com.adobe.images.JPGEncoder;
import flash.display.BitmapData;
import flash.display.MovieClip;
import flash.events.*;
import flash.geom.Matrix;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLRequestHeader;
import flash.net.URLRequestMethod;
import flash.net.navigateToURL;
import flash.utils.ByteArray;
// ImageSend - Dan Zen 2010
// create jpg and send image to url
public class ImageSend extends MovieClip {
private var bitmapData:BitmapData;
private var url:String;
public function ImageSend(theBitmapData:BitmapData, theURL:String, max:Number=1024) {
trace ("hi from ImageSend");
bitmapData = theBitmapData;
url = theURL;
if (bitmapData.height > max || bitmapData.width > max) {
var newW:Number;
var newH:Number;
var scale:Number;
if (bitmapData.height / bitmapData.width > 1) {
scale = max / bitmapData.height;
newW = bitmapData.width * scale;
newH = max;
} else {
scale = max / bitmapData.width
newH = bitmapData.height * scale;
newW = max;
}
var m:Matrix = new Matrix();
m.scale(scale,scale);
var bm:BitmapData = new BitmapData(newW, newH, false, 0);
bm.draw(bitmapData, m);
bitmapData = bm;
}
var myEncoder:JPGEncoder = new JPGEncoder(80);
var stream:ByteArray = myEncoder.encode(bitmapData);
var header:URLRequestHeader = new URLRequestHeader("Content-type", "application/octet-stream");
var jpgURLRequest:URLRequest;
var urlLoader:URLLoader;
jpgURLRequest = new URLRequest(url);
jpgURLRequest.requestHeaders.push(header);
jpgURLRequest.method = URLRequestMethod.POST;
jpgURLRequest.data = stream;
urlLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, imageComplete);
urlLoader.load(jpgURLRequest);
}
private function imageComplete(e:Event):void {
dispatchEvent(new Event(Event.COMPLETE));
}
}
}
package com.danzen.interfaces {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.MovieClip;
import flash.events.*;
import flash.geom.Matrix;
import flash.media.CameraRoll;
import flash.media.MediaPromise;
import flash.utils.Timer;
// MobileCamRoll - compiled from code on the web and wrapped by Dan Zen 2012
// tested with iOS, Android and Blackberry 10 (Playbook) used first on hangy.mobi then on hipster.mobi
// MobileCamRoll opens the camera roll on Mobile when you call getPhoto
// it then gives an Event.COMPLETE event with an error of "success" if no error
// and you can get the bitmapData property to get the picture data
// an Event.CANCEL is dispatched if cancelled
public class MobileCamRoll extends MovieClip {
public var bitmapData:BitmapData;
public var error:String;
private var max:Number;
public function MobileCamRoll() {
trace ("hi from MobileCamRoll");
}
public function getPhoto(theMax:Number=1024):void {
max = theMax
var t:Timer = new Timer(100,1);
t.addEventListener(TimerEvent.TIMER, go);
t.start();
}
private function go(e:TimerEvent):void {
var cr:CameraRoll=new CameraRoll();
var loader:Loader;
if (CameraRoll.supportsBrowseForImage == false) {
error = "Sorry, photo browsing not supported";
dispatchEvent(new Event(Event.COMPLETE));
return;
}
addBrowseListeners();
cr.browseForImage();
function addBrowseListeners():void {
cr.addEventListener(MediaEvent.SELECT, onImgSelect);
cr.addEventListener(Event.CANCEL, onCancel);
cr.addEventListener(ErrorEvent.ERROR, onError);
}
function removeBrowseListeners():void {
cr.removeEventListener(MediaEvent.SELECT, onImgSelect);
cr.removeEventListener(Event.CANCEL, onCancel);
cr.removeEventListener(ErrorEvent.ERROR, onError);
}
function onCancel(event:Event):void {
removeBrowseListeners();
dispatchEvent(new Event(Event.CANCEL));
}
function onError(event:ErrorEvent):void {
removeBrowseListeners();
error = "Sorry, error loading pic";
dispatchEvent(new Event(Event.COMPLETE));
}
function onImgSelect(event:MediaEvent):void {
var promise:MediaPromise = event.data as MediaPromise;
removeBrowseListeners();
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoaded);
loader.contentLoaderInfo.addEventListener(ErrorEvent.ERROR, onError);
loader.loadFilePromise(promise);
}
function onImageLoaded(event:Event):void {
bitmapData = Bitmap(event.currentTarget.content).bitmapData;
if (bitmapData.height > max || bitmapData.width > max) {
var newW:Number;
var newH:Number;
var scale:Number;
if (bitmapData.height / bitmapData.width > 1) {
scale = max / bitmapData.height;
newW = bitmapData.width * scale;
newH = max;
} else {
scale = max / bitmapData.width
newH = bitmapData.height * scale;
newW = max;
}
var m:Matrix = new Matrix();
m.scale(scale,scale);
var bm:BitmapData = new BitmapData(newW, newH, false, 0);
bm.draw(bitmapData, m);
bitmapData = bm;
}
loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onImageLoaded);
loader.contentLoaderInfo.removeEventListener(ErrorEvent.ERROR, onError);
error = "success";
dispatchEvent(new Event(Event.COMPLETE));
}
}
}
}
package com.danzen.interfaces {
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.display.MovieClip;
import flash.display.DisplayObject;
import flash.events.*;
import flash.geom.Matrix;
public class Rotator extends MovieClip {
private var image:DisplayObject;
private var button:MovieClip;
private var holder:MovieClip;
public static const ROTATE:String = "rotate";
public var bitmapData:BitmapData;
public function Rotator(theImage:DisplayObject, theButton:MovieClip) {
trace ("hi from Rotator");
image = theImage;
holder = MovieClip(image.parent);
button = theButton;
button.buttonMode = true;
button.addEventListener(MouseEvent.CLICK, doRotate);
bitmapData = new BitmapData(image.width, image.height, false, 0);
bitmapData.draw(image);
}
private function doRotate(e:MouseEvent):void {
// grab bitmapData from sample - would be the image complete
// rotate it with matrix removeChild old Bitmap and set to null
// add new Bitmap
// store the bitmapData to create the crop pic
var matrix:Matrix = new Matrix();
matrix.translate(-bitmapData.width / 2, -bitmapData.height / 2);
matrix.rotate(90 * (Math.PI / 180));
matrix.translate(bitmapData.height / 2, bitmapData.width / 2);
var bmd:BitmapData = new BitmapData(bitmapData.height, bitmapData.width, false, 0x00000000);
bmd.draw(bitmapData, matrix);
bitmapData = bmd;
var temp:DisplayObject = holder.getChildAt(0);
holder.removeChild(temp);
temp = null;
holder.addChild(new Bitmap(bitmapData));
dispatchEvent(new Event(Rotator.ROTATE));
}
public function dispose():void {
button.removeEventListener(MouseEvent.CLICK, doRotate);
bitmapData = null;
}
}
}
package com.danzen.interfaces {
import flash.display.MovieClip;
import flash.events.*;
import flash.text.TextField;
public class TextScroll extends MovieClip {
// scrolls a text field based on swipe type movement
private var t:TextField;
private var startY:Number;
private var lastY:Number;
private var startS:Number;
private var lastD:Number;
private var sensitivity:Number; // 1 mobile, .05 web
public function TextScroll(theTextField:TextField, theSensitivity:Number = 1):void {
sensitivity = theSensitivity;
t = theTextField;
t.addEventListener(MouseEvent.MOUSE_DOWN, doDown);
t.addEventListener(Event.CHANGE, testScroll);
}
public function testScroll():Boolean {
if (t.maxScrollV > 1) {
return true;
} else {
return false;
}
}
private function doDown(e:MouseEvent):void {
lastY = startY = mouseY;
startS = t.scrollV;
t.stage.addEventListener(MouseEvent.MOUSE_MOVE, doScroll);
t.stage.addEventListener(MouseEvent.MOUSE_UP, doUP);
}
private function doScroll(e:MouseEvent):void {
var newV:Number = startS - (mouseY-startY)*sensitivity;
trace (sensitivity, newV);
t.scrollV = Math.min(t.maxScrollV, Math.max(0, newV));
}
private function doUP(e:MouseEvent):void {
t.stage.removeEventListener(MouseEvent.MOUSE_MOVE, doScroll);
t.stage.removeEventListener(MouseEvent.MOUSE_UP, doUP);
}
}
}