PageRenderTime 55ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/flash/src/mma/view/item/LargePictureItem.as

https://github.com/proflexor/MikesFlickrWall
ActionScript | 597 lines | 447 code | 126 blank | 24 comment | 61 complexity | 7b0bcc600ff449f13ef92b7f8cea58b8 MD5 | raw file
  1. package mma.view.item
  2. {
  3. import flash.display.Loader;
  4. import flash.display.Sprite;
  5. import flash.events.Event;
  6. import flash.filters.DropShadowFilter;
  7. import flash.geom.Matrix;
  8. import flash.geom.Point;
  9. import flash.geom.Rectangle;
  10. import flash.net.URLRequest;
  11. import flashx.textLayout.operations.CutOperation;
  12. import gl.events.GestureEvent;
  13. import gl.events.TouchEvent;
  14. import id.core.TouchSprite;
  15. import mma.custom.event.StringEvent;
  16. import mma.data.flickr.PhotoData;
  17. import mma.model.FlickrModel;
  18. import mma.model.ModelLocator;
  19. import mma.model.TouchPoint;
  20. import mx.utils.UIDUtil;
  21. public class LargePictureItem extends TouchSprite
  22. {
  23. private static const GRAD_PI:Number = 180/Math.PI;
  24. private static const NONE:String = "none";
  25. private static const DRAGGING:String = "dragging";
  26. private static const ROTATE_SCALE:String = "rotateScale";
  27. private var blobs: Array = [];
  28. private var blob1:Object;
  29. private var blob2:Object;
  30. private var pointMap:Object = {};
  31. private var state:String;
  32. private var photoData:PhotoData;
  33. public var guid:String;
  34. private var container:TouchSprite;
  35. private var loader:Loader;
  36. //animation vars.
  37. private var angle:Number = 0;
  38. private var speed:Number = 0.2;
  39. private var destWidth:Number;
  40. private var destHeight:Number;
  41. private var rotateX:Number;
  42. private var rotateY:Number;
  43. private var startX:Number;
  44. private var startY:Number;
  45. private var startW:Number;
  46. private var startH:Number;
  47. private var closeXpos:Number;
  48. private var closeYpos:Number;
  49. private var secondTID:String;
  50. private var firstAngle:Number;
  51. private var maxH:Number;
  52. private var maxW:Number;
  53. private var minH:Number;
  54. private var minW:Number;
  55. private var bW:Number;
  56. private var bH:Number;
  57. private var startD:Number;
  58. private var startCenter:Point;
  59. private var widthRatio:Number;
  60. private var resizeBtn:Sprite;
  61. private var closeBtn:TouchSprite;
  62. private var resizeButtonTouched:Boolean = false;
  63. [Embed(source="/asset/flash/ImageWallAsset.swf", symbol="CloseBtn")]
  64. public var CloseBtn:Class;
  65. [Embed(source="/asset/flash/ImageWallAsset.swf", symbol="ResizeIcon")]
  66. public var ResizeBtn:Class;
  67. public function LargePictureItem(d:PhotoData)
  68. {
  69. photoData = d;
  70. addEventListener(Event.ADDED_TO_STAGE, onAddedToStaged);
  71. guid = UIDUtil.createUID();
  72. }
  73. private function onAddedToStaged(event:Event):void
  74. {
  75. event.stopImmediatePropagation();
  76. state = NONE;
  77. container = new Sprite();
  78. addChild(container);
  79. loader = new Loader();
  80. loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaderComplete);
  81. loader.load(new URLRequest(photoData.large.source));
  82. closeBtn = new CloseBtn();
  83. closeBtn.buttonMode = true;
  84. resizeBtn = new ResizeBtn();
  85. resizeBtn.buttonMode = true;
  86. //closeBtn.visible = false;
  87. }
  88. private function addTouchEvent():void
  89. {
  90. photoData.showThumb = false;
  91. closeBtn.x = loader.content.width - 25;
  92. closeBtn.y = - 25;
  93. container.addChild(closeBtn);
  94. resizeBtn.x = loader.content.width - 25;
  95. resizeBtn.y = loader.content.height - 25;
  96. container.addChild(resizeBtn);
  97. this.blobContainerEnabled = true;
  98. closeBtn.addEventListener(TouchEvent.TOUCH_TAP, onCloseHandler);
  99. // resizeBtn.addEventListener(TouchEvent.TOUCH_BEGIN, onResizeHandler);
  100. // resizeBtn.addEventListener(TouchEvent.TOUCH_END, onTouchUpHandler);
  101. // loader.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchDownHandler);
  102. // loader.addEventListener(TouchEvent.TOUCH_END, onTouchUpHandler);
  103. // addEventListener(TouchEvent.TOUCH_MOVE, onTouchMoveHandler);
  104. loader.addEventListener(TouchEvent.TOUCH_DOWN, startDrag_Press);
  105. loader.addEventListener(TouchEvent.TOUCH_UP, stopDrag_Release);
  106. loader.addEventListener(GestureEvent.GESTURE_ROTATE, gestureRotateHandler);
  107. loader.addEventListener(GestureEvent.GESTURE_SCALE, gestureScaleHandler);
  108. container.transform.matrix =
  109. new Matrix(1, 0, 0, 1, -width/2,
  110. -height/2);
  111. this.x = this.x + width/2;
  112. this.y = this.y + height/2;
  113. trace("x: " + x);
  114. trace("y: " + y);
  115. trace("width: " + width);
  116. trace("height: " + height);
  117. }
  118. private function addBlob(id:int, originX:Number, originY:Number):void
  119. {
  120. for(var i:int = 0; i < blobs.length; i++)
  121. {
  122. if(blobs[i].id == id)
  123. {
  124. if(blobs.length == 1)
  125. {
  126. blob1 = blobs[i];
  127. delete pointMap[blob2.id];
  128. blob2 = null;
  129. }
  130. else(blobs. length == 2)
  131. {
  132. blob1 = blobs[0];
  133. blob2 = blobs[1];
  134. }
  135. return;
  136. }
  137. }
  138. blobs.push({id:id, originX:originX, originY:originY, myOriginX:this.x, myOriginY:this.y});
  139. if(blobs.length == 1)
  140. {
  141. state = DRAGGING;
  142. blob1 = blobs[0];
  143. }
  144. else if(blobs.length == 2)
  145. {
  146. state = ROTATE_SCALE;
  147. blob1 = blobs[0];
  148. blob2 = blobs[1];
  149. var tObject1:Object = pointMap[blob1.id];
  150. var tObject2:Object = pointMap[blob2.id];
  151. if(tObject1)
  152. {
  153. var curP1:Point = (new Point(tObject1.x, tObject1.y));
  154. blob1.originX = curP1.x;
  155. blob1.originY = curP1.y;
  156. }
  157. }
  158. }
  159. private function removeBlob(id:int):void
  160. {
  161. trace("removeBlob");
  162. for(var i:int=0; i<blobs.length; i++)
  163. {
  164. if(blobs[i].id == id)
  165. {
  166. blobs.splice(i, 1);
  167. if(blobs.length == 0)
  168. {
  169. state = NONE;
  170. showBorder();
  171. }
  172. if(blobs.length == 1)
  173. {
  174. state = DRAGGING;
  175. blob1 = blobs[0];
  176. delete pointMap[blob2.id];
  177. blob2 = null;
  178. }
  179. if(blobs.length >= 2) {
  180. state = ROTATE_SCALE;
  181. blob1 = blobs[0];
  182. blob2 = blobs[1];
  183. }
  184. return;
  185. }
  186. }
  187. }
  188. private function onCloseHandler(event:TouchEvent):void
  189. {
  190. var flickrModel:FlickrModel = ModelLocator.getInstance().flickrModel;
  191. flickrModel.isClosing = true;
  192. event.stopImmediatePropagation();
  193. closeBtn.removeEventListener(TouchEvent.TOUCH_BEGIN, onCloseHandler);
  194. // resizeBtn.removeEventListener(TouchEvent.TOUCH_BEGIN, onResizeHandler);
  195. // loader.removeEventListener(TouchEvent.TOUCH_BEGIN, onTouchDownHandler);
  196. // loader.removeEventListener(TouchEvent.TOUCH_END, onTouchUpHandler);
  197. trace("close LargePictureItem");
  198. photoData.showThumb = true;
  199. var e:StringEvent = new StringEvent("RemoveLargeImage", this.guid);
  200. dispatchEvent(e);
  201. trace(e);
  202. }
  203. private function onTouchMoveHandler(event:TouchEvent):void
  204. {
  205. var p:Point = new Point(event.stageX, event.stageY);
  206. var cntr:Point = new Point(this.x, this.y);
  207. var radius:Number = Math.sqrt((this.height*this.height + this.width*this.width))/4;
  208. //trace(radius + "," + Point.distance(p, cntr));
  209. //trace("MoveTest: " + (Point.distance(p, cntr) > (radius + 20)));
  210. if(Point.distance(p, cntr) > (radius + 20))
  211. {
  212. removeBlob(event.touchPointID);
  213. return;
  214. }
  215. else
  216. {
  217. if(event.stageX == 0 && event.stageY == 0)
  218. {
  219. p = new Point(event.localX, event.localY);
  220. }
  221. else
  222. {
  223. p = new Point(event.stageX, event.stageY);
  224. }
  225. if ( pointMap[ event.touchPointID.toString() ] )
  226. {
  227. pointMap[ event.touchPointID.toString() ].x = p.x;
  228. pointMap[ event.touchPointID.toString() ].y = p.y;
  229. }
  230. }
  231. }
  232. private function onTouchDownHandler(event:TouchEvent):void
  233. {
  234. var p:Point;
  235. if(event.stageX == 0 && event.stageY == 0)
  236. {
  237. p = new Point(event.localX, event.localY);
  238. }
  239. else
  240. {
  241. p = new Point(event.stageX, event.stageY);
  242. }
  243. trace(p);
  244. pointMap[event.touchPointID.toString()] = p;
  245. addBlob(event.touchPointID, p.x, p.y);
  246. trace("TouchDown State: " + state + " with " + blobs.length);
  247. resizeButtonTouched = false;
  248. if(state == DRAGGING)
  249. {
  250. trace("touchDown : 1, ID: " + event.touchPointID);
  251. trace(blobs[0].id);
  252. removeEventListener(Event.ENTER_FRAME, onRotateEnterFrame);
  253. removeEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
  254. addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
  255. var pt:Point = p;
  256. startX = pt.x;
  257. startY = pt.y;
  258. closeBtn.visible = false;
  259. }
  260. if(state == ROTATE_SCALE)
  261. {
  262. trace("touchDown : 2, ID: " + blobs[0].id + blobs[1].id);
  263. removeEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
  264. removeEventListener(Event.ENTER_FRAME, onRotateEnterFrame);
  265. addEventListener(Event.ENTER_FRAME, onRotateEnterFrame);
  266. if(!blob1)
  267. {
  268. removeBlob(blob1.id);
  269. return;
  270. }
  271. var curPt:Point = (new Point(blob1.x, blob1.y));
  272. if(!blob2)
  273. {
  274. removeBlob(blob2.id);
  275. return;
  276. }
  277. var curPt2:Point = (new Point(blob2.x, blob2.y));
  278. startD = Point.distance(curPt, curPt2);
  279. startCenter = Point.interpolate(curPt, curPt2, 0.5);
  280. //var dx:Number = touchPoint1.x - touchPoint2.x;
  281. //var dy:Number = touchPoint1.y - touchPoint2.y;
  282. var dx:Number ,dy:Number;
  283. bW = loader.content.width;
  284. bH = loader.content.height;
  285. var origAngle:Point = curPt.subtract(curPt2);
  286. firstAngle = getAngleTrig(origAngle.x, origAngle.y);
  287. }
  288. }
  289. private function onRotateEnterFrame(event:Event):void
  290. {
  291. if(state != ROTATE_SCALE)
  292. {
  293. return;
  294. }
  295. if(!blob1|| !blob2)
  296. {
  297. removeEventListener(Event.ENTER_FRAME, onRotateEnterFrame);
  298. return;
  299. }
  300. var ptn:Point = (new Point(blob1.x, blob1.y));
  301. var ptn2:Point = (new Point(blob2.x, blob2.y));
  302. var ctr:Point = Point.interpolate(ptn, ptn2, 0.5);
  303. if(Point.distance(ctr, startCenter) > 0 )
  304. {
  305. this.x += ctr.x - startCenter.x;
  306. this.y += ctr.y - startCenter.y;
  307. startCenter = ctr;
  308. }
  309. var curAngle:Point = ptn.subtract(ptn2);
  310. var dis:Number = Point.distance(ptn, ptn2);
  311. var ratio:Number = dis / startD;
  312. var tempR:Number = this.rotation;
  313. this.rotation = 0;
  314. var newW:Number = bW * ratio;
  315. var newH:Number = bH * ratio;
  316. if(newW < maxW && newW > minW)
  317. {
  318. loader.content.width = newW;
  319. loader.content.height = newH;
  320. closeBtn.x = loader.content.width - 25;
  321. closeBtn.y = - 25;
  322. resizeBtn.x = loader.content.width - 25;
  323. resizeBtn.y = loader.content.height - 25;
  324. this.container.width = loader.content.width;
  325. this.width = loader.content.width;
  326. this.container.height = loader.content.height;
  327. this.height = loader.content.height;
  328. container.transform.matrix =
  329. new Matrix(1, 0, 0, 1, -width/2,
  330. -height/2);
  331. }
  332. var angle:Number = getAngleTrig(curAngle.x, curAngle.y);
  333. if(Math.abs(angle - firstAngle) > 2)
  334. {
  335. trace("rotation displacement: " + (angle - firstAngle));
  336. trace(ptn);
  337. trace(ptn2);
  338. }
  339. this.rotation = tempR + angle - firstAngle;
  340. firstAngle = angle;
  341. }
  342. private function onEnterFrameHandler(event:Event):void
  343. {
  344. var r:Rectangle = new Rectangle(0, 0, 2560, 1460);
  345. var ptn:Point = (new Point(blob1.x, blob1.y));
  346. /*trace(ptn);
  347. trace(this.x);
  348. trace(this.y);*/
  349. //trace(r.contains(touchPoint1.x, touchPoint1.y));
  350. if(r.contains(ptn.x, ptn.y))
  351. {
  352. this.x += (ptn.x - startX);
  353. this.y += (ptn.y - startY);
  354. }
  355. startX = ptn.x;
  356. startY = ptn.y;
  357. }
  358. private function onTouchUpHandler(event:TouchEvent):void
  359. {
  360. removeBlob(event.touchPointID);
  361. delete pointMap[event.touchPointID.toString()];
  362. loader.removeEventListener(TouchEvent.TOUCH_BEGIN, onTouchDownHandler);
  363. loader.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchDownHandler);
  364. removeEventListener(Event.ENTER_FRAME, onRotateEnterFrame);
  365. // removeEventListener(Event.ENTER_FRAME, onResizeEnterFrame);
  366. removeEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
  367. // resizeBtn.removeEventListener(TouchEvent.TOUCH_BEGIN, onResizeHandler);
  368. // resizeBtn.addEventListener(TouchEvent.TOUCH_BEGIN, onResizeHandler);
  369. //addEventListener(TouchEvent.TOUCH_END, onTouchUpHandler);
  370. if(state == NONE)
  371. {
  372. showBorder();
  373. }
  374. if(state == DRAGGING && blobs.length == 1)
  375. {
  376. var pt:Point = new Point(blob1.originX, blob1.originY);
  377. //trace("ptpt:"+pt);
  378. //trace(blob1.originX, blob1.originY);
  379. trace("before taking finger off: " + x +", " + y);
  380. startX = pt.x;
  381. startY = pt.y;
  382. addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
  383. }
  384. trace("TouchUp State: " + state + " with " + blobs.length);
  385. }
  386. private function onLoaderComplete(event:Event):void
  387. {
  388. event.stopImmediatePropagation();
  389. container.addChild(loader);
  390. loader.visible = false;
  391. maxW = loader.content.width;
  392. maxH = loader.content.height;
  393. trace("maximum dimension: "+ maxW + ", "+ maxH);
  394. widthRatio = loader.content.width/loader.content.height;
  395. loader.content.width = loader.content.width/2;
  396. loader.content.height = loader.content.height/2;
  397. minW = loader.content.width;
  398. minH = loader.content.height;
  399. destWidth = loader.content.width;
  400. destHeight = loader.content.height;
  401. loader.content.width = 75;
  402. loader.content.height = 75;
  403. var drop:DropShadowFilter = new DropShadowFilter(15, 0, 0xefefef, 1, 0, 0, 7.0);
  404. var drop2:DropShadowFilter = new DropShadowFilter(15, 90, 0xefefef, 1, 0, 0, 7.0);
  405. var drop3:DropShadowFilter = new DropShadowFilter(15, 180, 0xefefef, 1, 0, 0, 7.0);
  406. var drop4:DropShadowFilter = new DropShadowFilter(15, 270, 0xefefef, 1, 0, 0, 7.0);
  407. var ary:Array = [];
  408. ary.push(drop);
  409. ary.push(drop2);
  410. ary.push(drop3);
  411. ary.push(drop4);
  412. loader.filters = ary;
  413. removeEventListener(Event.ENTER_FRAME, onShowImageEnterFrame)
  414. addEventListener(Event.ENTER_FRAME, onShowImageEnterFrame)
  415. loader.visible = true;
  416. }
  417. private function showBorder():void
  418. {
  419. closeBtn.visible = true;
  420. }
  421. private function hideBorder():void
  422. {
  423. closeBtn.visible = false;
  424. }
  425. private function onShowImageEnterFrame(event:Event):void
  426. {
  427. var v:Number = Math.sin(angle);
  428. angle += speed;
  429. var w:Number = v * destWidth + 75;
  430. var h:Number = v * destHeight + 75;
  431. var a:Number = v * .5;
  432. loader.content.width = w;
  433. loader.content.height = h;
  434. loader.content.alpha = a + .5;
  435. var degree:Number = angle * (180/Math.PI);
  436. if(degree >= 90)
  437. {
  438. removeEventListener(Event.ENTER_FRAME, onShowImageEnterFrame)
  439. addTouchEvent();
  440. }
  441. }
  442. protected function getAngleTrig(X:Number, Y:Number):Number
  443. {
  444. if (X == 0.0)
  445. {
  446. if(Y < 0.0)
  447. return 270;
  448. else
  449. return 90;
  450. } else if (Y == 0)
  451. {
  452. if(X < 0)
  453. return 180;
  454. else
  455. return 0;
  456. }
  457. if ( Y > 0.0)
  458. {
  459. if (X > 0.0)
  460. return Math.atan(Y/X) * GRAD_PI;
  461. else
  462. return 180.0-Math.atan(Y/-X) * GRAD_PI;
  463. }
  464. else
  465. if (X > 0.0)
  466. return 360.0-Math.atan(-Y/X) * GRAD_PI;
  467. else
  468. return 180.0+Math.atan(-Y/-X) * GRAD_PI;
  469. }
  470. }
  471. }