Skip to content

Instantly share code, notes, and snippets.

@mani95lisa
Created July 2, 2013 13:59
Show Gist options
  • Save mani95lisa/5909540 to your computer and use it in GitHub Desktop.
Save mani95lisa/5909540 to your computer and use it in GitHub Desktop.
package
{
import flash.display.DisplayObject;
import flash.display.GradientType;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.utils.getTimer;
/*
Book Class by TimoZachi
Please read before using (sorry about my bad english):
public properties definitions:
*pageWidth: defines the width of the page.
*pageHeight: defines the height of the page;
*pageDelay: a number between 1 and 8 that defines the mouse easing, pageDelay
also aplies to how long the page take to autoFlip when the user drops it;
*minMouseX: a number between 0 and the page width divided by 12 that defines the minimum mouse x position
counting from the corner that the user moused down.
*cornerSize: defines the corner size that will detect mouse over and mouse down, any object under the
corner area will not receive mouse events.
*width(overrided): defines the width of the book.
*height(overrided): defines the height of the book.
*currentPageNum(read only): represents the number of open page(the page that's visible) on left
*maxPagesOverlapping: a uint that defines the max number of pages that overlap each other. if none
of your pages are transparent, set it to 2.
*totalPagesNum: the total number of pages.
public methods definition:
*addPages: add pages to your book
param ...pages: rest param, you can put as many pages you want as parameters of the method, all of them
need to extend DisplayObject.
*start: starts the book, to use the gotoPage() method you have to run start.
param visiblePageNum: the page that will be open on start
*flipToPage: flip the pages to the page you want, mouse interactions are disabled while flipping.
param pageNum: the number of the page you want to go.
param speed: a number from 0 to 10 that defines how fast the pages shoud be flipped
param oneFlip: a boolean defining whether the book will do only one flip to go to the desired page,
this option has a bug, so use it only when you have a big book.
Also if you have transparent pages on your book live it to false.
*getPageAt: returns the page at the specified index.
param index: the index of the page (first page index is 0 and last pages index is totalPagesNum - 1)
if you would like to change the gradient of the page and/or the shadows, they are drawn in the private
function drawGrads. the flipGradMask is the gradient that stays over the page your flipping. the page
shadow is the gradient that stays under the page your flipping. and the shadow behind is the shadow on
the other side of the pageShadow. to change the gradients of the page, they are drawn in the function
"addGradToPage".
*/
public class Book extends Sprite
{
private var currentCorner:String;
private var direction:String;
private var currentCornerSprite:Sprite;
private var axis:Sprite;
private var checkOver:Boolean = true;
private var checkOverAutomatic:Boolean = true;
private var randomFlip:Number;
private var oneFlip:Boolean;
private var canDrag:Boolean = false;
private var isDown:Boolean = false;
private var autoFlip:Boolean = false;
private var flipFoward:Boolean;
private var pageFlipStarted:Boolean = false;
private var pgDiagonal:Number;
private var pgDiagonalAngle:Number;
private var newVisiblePageNumOnLeft:int;
private var visiblePageNumOnLeft:int;
private var gotoPageNum:int;
private var newGotoSpeed:Number;
private var automaticPageDelay:Number;
private var completeFactor:int = 3;
private var mouseOutFunction:Function;
private var translatorFunction:Function;
private var prevX:Number = 0;
private var prevY:Number = 0;
private var destX:Number = 0;
private var destY:Number = 0;
private var angle:Number = 0;
private var pageTL:Point;
private var pageDL:Point;
private var pageDR:Point;
private var originalMouse:Point;
private var pt1:Point;
private var pt2:Point;
private var pt3:Point;
private var pageLocation:Point;
private var pagesContainer:Sprite;
private var saflip:Sprite;
private var cornersHolder:Sprite;
private var pageFlipping:Sprite;
private var pageFlippingMask:Shape;
private var currentPage:Sprite;
private var currentPageMask:Shape;
private var flipGrad:Shape;
private var flipGradMask:Shape;
private var pageShadow:Shape;
private var pageShadowMask:Shape;
private var pageShadowBehind:Shape;
private var pageShadowBehindMask:Shape;
private var rawPagesVect:Vector.<DisplayObject>;
private var pagesVect:Vector.<Sprite>;
private var pgW:uint;
private var pgH:uint;
private var _pageDelay:Number;
private var _minMouseX:Number;
private var _cornerSize:Number;
private var _maxPagesOverlapping:uint;
//constructor
public function Book(pageWidth:uint = 300, pageHeight:uint = 375, cornerSize:Number = 50, pageDelay:Number = 4, minMouseX:Number = 10, maxPagesOverlapping:uint = 3)
{
this.pgW = pageWidth;
this.pgH = pageHeight;
this.pageDelay = pageDelay;
this.minMouseX = minMouseX;
this._cornerSize = cornerSize;
this.maxPagesOverlapping = maxPagesOverlapping;
setDiagonals();
setProps();
drawMasks();
drawGrads();
drawCorners();
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
//PUBLIC METHODS
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
public function addPages(...pages):void
{
for(var i:int = 0; i < pages.length; i++)
{
var currentPageHolder:Sprite = new Sprite();
currentPageHolder.addChild(pages[i] as DisplayObject);
addGradToPage(currentPageHolder, pagesVect.length % 2, pages[i].width, pages[i].height);
currentPageHolder.width = pgW;
currentPageHolder.height = pgH;
if(pageFlipStarted &amp;&amp; pagesVect.length % 2 == 0)
{
currentPageHolder.x = pgW;
if(visiblePageNumOnLeft + 1 > pagesVect.length - maxPagesOverlapping * 2)
{
pagesContainer.addChildAt(currentPageHolder, 0);
}
}
rawPagesVect.push(pages[i] as DisplayObject);
pagesVect.push(currentPageHolder);
}
}
public function start(visiblePageNum:int):void
{
if(visiblePageNum % 2 == 0)
{
visiblePageNum--;
}
setUpPages(visiblePageNum);
visiblePageNumOnLeft = visiblePageNum;
this.addEventListener(Event.ENTER_FRAME, onEnter);
pageFlipStarted = true;
}
public function flipToPage(pageNum:int, speed:Number = 8, oneFlip:Boolean = false):void
{
if(!pageFlipStarted)
{
trace("please start() the book before u can use gotoPage!!");
return;
}
if(pageNum % 2 == 0){pageNum--;}
else if(pageNum > pagesVect.length - 1)
{
pageNum = pagesVect.length - 1;
}
else if(pageNum < -1)
{
pageNum = -1;
}
if(speed > 10){speed == 10}
else if(speed < 0){speed == 0}
this.gotoPageNum = pageNum;
this.oneFlip = oneFlip;
newGotoSpeed = 8 - ((speed / 10) * 6.8);
trace("flip automaticaly to pages", pageNum, "and" ,pageNum + 1, "on speed", speed);
this.addEventListener(Event.ENTER_FRAME, onEnterAutomatic);
}
public function getPageAt(index:int):DisplayObject
{
if(index > rawPagesVect.length - 1)
{
trace("index to big");
return null;
}
else if(index < 0)
{
trace("index to low");
return null;
}
return rawPagesVect[index] as DisplayObject;
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
//PRIVATE METHODS
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
private function setDiagonals():void
{
pgDiagonal = Math.sqrt(Math.pow(pgW, 2) + Math.pow(pgH, 2));
pgDiagonalAngle = Math.atan2(pgW, pgH);
}
private function setProps():void
{
pageTL = new Point();
pageDL = new Point();
pageDR = new Point();
pt1 = new Point();
pt2 = new Point();
pt3 = new Point();
originalMouse = new Point();
pageLocation = new Point();
rawPagesVect = new Vector.<DisplayObject>();
pagesVect = new Vector.<Sprite>();
pagesContainer = new Sprite();
this.addChild(pagesContainer);
saflip = new Sprite();
this.addChild(saflip);
cornersHolder = new Sprite();
this.addChild(cornersHolder);
axis = new Sprite();
this.addChild(axis);
pageFlippingMask = new Shape();
pageFlippingMask.visible = false;
saflip.addChild(pageFlippingMask);
currentPageMask = new Shape();
currentPageMask.visible = false;
pagesContainer.addChild(currentPageMask);
pageShadowMask = new Shape();
pageShadowMask.visible = false;
saflip.addChild(pageShadowMask);
pageShadowBehindMask = new Shape();
pageShadowBehindMask.visible = false;
saflip.addChild(pageShadowBehindMask);
flipGradMask = new Shape();
flipGradMask.visible = false;
saflip.addChild(flipGradMask);
pageShadow = new Shape();
pageShadow.visible = false;
pageShadow.mask = pageShadowMask;
saflip.addChild(pageShadow);
pageShadowBehind = new Shape();
pageShadowBehind.visible = false;
pageShadowBehind.mask = pageShadowBehindMask;
saflip.addChild(pageShadowBehind);
flipGrad = new Shape();
flipGrad.visible = false;
flipGrad.mask = flipGradMask;
saflip.addChild(flipGrad);
}
private function drawMasks():void
{
pageFlippingMask.graphics.clear();
pageFlippingMask.graphics.lineStyle();
pageFlippingMask.graphics.beginFill(0xFF00, .3);
pageFlippingMask.graphics.drawRect(-pgDiagonal - 10, -pgH * 1.4 / 2, pgDiagonal + 10, pgH * 1.4);
pageFlippingMask.graphics.endFill();
currentPageMask.graphics.clear();
currentPageMask.graphics.lineStyle();
currentPageMask.graphics.beginFill(0xFF, .3);
currentPageMask.graphics.drawRect(-pgDiagonal - 10, -pgH, pgDiagonal + 10, pgH * 2);
currentPageMask.graphics.endFill();
pageShadowMask.graphics.clear();
pageShadowMask.graphics.lineStyle();
pageShadowMask.graphics.beginFill(0x888888);
pageShadowMask.graphics.drawRect(0, 0, 2 * pgW, pgH);
pageShadowMask.graphics.endFill();
pageShadowBehindMask.graphics.clear();
pageShadowBehindMask.graphics.lineStyle();
pageShadowBehindMask.graphics.beginFill(0x888888);
pageShadowBehindMask.graphics.drawRect(0, 0, 2 * pgW, pgH);
pageShadowBehindMask.graphics.endFill();
flipGradMask.graphics.clear();
flipGradMask.graphics.lineStyle();
flipGradMask.graphics.beginFill(0x888888);
flipGradMask.graphics.drawRect(0, 0, pgW, pgH);
flipGradMask.graphics.endFill();
}
function drawGrads():void
{
var mat:Matrix = new Matrix();
mat.createGradientBox(pgW, pgH, 0, -pgW);
pageShadow.graphics.clear();
pageShadow.graphics.lineStyle();
pageShadow.graphics.beginGradientFill(GradientType.LINEAR, [0, 0], [0, .5], [0, 255], mat);
pageShadow.graphics.drawRect(-pgW, -pgDiagonal, pgW, pgDiagonal * 2);
pageShadow.graphics.endFill();
var mat2:Matrix = new Matrix();
mat2.createGradientBox(pgW, pgH, 0, 0);
pageShadowBehind.graphics.clear();
pageShadowBehind.graphics.lineStyle();
pageShadowBehind.graphics.beginGradientFill(GradientType.LINEAR, [0, 0], [.5, 0], [0, 255], mat2);
pageShadowBehind.graphics.drawRect(0, -(pgDiagonal + 50)/2, pgW, pgDiagonal + 50);
pageShadowBehind.graphics.endFill();
flipGrad.graphics.clear();
flipGrad.graphics.lineStyle();
flipGrad.graphics.beginGradientFill(GradientType.LINEAR, [0xFFFFFF, 0xFFFFFF, 0, 0], [0, .10, .30, .10], [0, 127, 220, 255], mat);
flipGrad.graphics.drawRect(-pgW, -(pgDiagonal + 50)/2, pgW, pgDiagonal + 50);
flipGrad.graphics.endFill();
}
private function drawCorners():void
{
var corner1:Sprite = new Sprite();
corner1.graphics.beginFill(0x888888, 0);
corner1.graphics.drawRect(0, 0, _cornerSize, _cornerSize);
cornersHolder.addChild(corner1);
var corner2:Sprite = new Sprite();
corner2.graphics.beginFill(0x888888, 0);
corner2.graphics.drawRect(0, 0, -_cornerSize, _cornerSize);
corner2.x = 2 * pgW;
cornersHolder.addChild(corner2);
var corner3:Sprite = new Sprite();
corner3.graphics.beginFill(0x888888, 0);
corner3.graphics.drawRect(0, 0, -_cornerSize, -_cornerSize);
corner3.x = 2 * pgW;
corner3.y = pgH;
cornersHolder.addChild(corner3);
var corner4:Sprite = new Sprite();
corner4.graphics.beginFill(0x888888, .0);
corner4.graphics.drawRect(0, 0, _cornerSize, -_cornerSize);
corner4.y = pgH;
cornersHolder.addChild(corner4);
}
private function setUpPages(pageOnLeftNum:int):void
{
var total:int = pagesVect.length;
for(var i:int = 1; i <= pageOnLeftNum; i += 2)
{
var page:Sprite = pagesVect[i];
page.x = 0;
page.y = 0;
if((pageOnLeftNum - i)/2 < _maxPagesOverlapping)
{
pagesContainer.addChild(page);
}
}
for(var j:int = total - 2; j > pageOnLeftNum; j -= 2)
{
var page2:Sprite = pagesVect[j];
page2.x = pgW;
page2.y = 0;
if((j - pageOnLeftNum + 1)/2 <= _maxPagesOverlapping)
{
pagesContainer.addChild(page2);
}
}
}
private function addGradToPage(page:Sprite, pageSide:int, w:Number, h:Number):void
{
var mat:Matrix = new Matrix();
var shad:Shape = new Shape();
if(pageSide == 0)
{
mat.createGradientBox(w/5, h)
shad.graphics.lineStyle();
shad.graphics.beginGradientFill(GradientType.LINEAR, [0, 0, 0], [.6, .5, 0], [0, 15, 255], mat);
shad.graphics.drawRect(0, 0, w/5, h);
shad.graphics.endFill();
page.addChild(shad);
}
else
{
mat.createGradientBox(w/5, h, 0, -w/5)
shad.graphics.lineStyle();
shad.graphics.beginGradientFill(GradientType.LINEAR, [0, 0, 0], [0, .5, .6], [0, 240, 255], mat);
shad.graphics.drawRect(-w/5, 0, w/5, h);
shad.graphics.endFill();
shad.x = w;
page.addChild(shad);
}
}
private function onEnter(event:Event):void
{
if(checkOver)
{
if(checkOverCorners())
{
checkOver = false;
canDrag = true;
//trace("over");
cornersHolder.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
prevX = 0;
prevY = 0;
destX = 0;
destY = 0;
saflip.addChildAt(pageFlipping, 5);
pageFlipping.mask = pageFlippingMask;
currentPage.mask = currentPageMask;
flipGrad.visible = true;
pageShadow.visible = true;
pageShadowBehind.visible = true;
this.dispatchEvent(new PageEvent(PageEvent.MOUSE_AT_CORNER, direction, currentCorner, visiblePageNumOnLeft));
}
}
if(canDrag)
{
if(mouseOutFunction() &amp;&amp; !isDown)
{
//trace("out");
canDrag = false;
autoFlip = true;
flipFoward = false;
prevX = destX = originalMouse.x;
prevY = destY = originalMouse.y;
cornersHolder.removeEventListener(MouseEvent.MOUSE_DOWN, onDown);
}
else
{
setCordsByMouse();
movePages();
}
}
else if(autoFlip)
{
var finishFlipping:Boolean = setCordsByAutoFlip();
if(finishFlipping)
{
movePages();
if(flipFoward)
{
pagesContainer.removeChild(currentPage);
pageFlipping.mask = null;
visiblePageNumOnLeft = newVisiblePageNumOnLeft;
setPagesVisibility();
this.dispatchEvent(new PageEvent(PageEvent.PAGE_FLIPPED, direction, currentCorner, visiblePageNumOnLeft));
}
else
{
saflip.removeChild(pageFlipping);
currentPage.mask = null;
this.dispatchEvent(new PageEvent(PageEvent.PAGE_FLIP_CANCELED, direction, currentCorner, visiblePageNumOnLeft));
}
autoFlip = false;
checkOver = true;
flipGrad.visible = false;
pageShadow.visible = false;
pageShadowBehind.visible = false;
}
else
{
movePages();
}
}
}
private function onEnterAutomatic(event:Event):void
{
if(!autoFlip)
{
flipFoward = true;
this.completeFactor = pgW / (automaticPageDelay * 12);
this.removeEventListener(Event.ENTER_FRAME, onEnter);
if(checkOverAutomatic)
{
this.automaticPageDelay = newGotoSpeed;
if(gotoPageNum > visiblePageNumOnLeft)
{
if(oneFlip/* &amp;&amp; gotoPageNum - visiblePageNumOnLeft != 2*/)
{
setPagesOneFlip("to left", gotoPageNum);
}
else
{
setPagesAutomatic("to left");
}
}
else if(gotoPageNum < visiblePageNumOnLeft)
{
if(oneFlip &amp;&amp; visiblePageNumOnLeft - gotoPageNum != 2)
{
setPagesOneFlip("to right", gotoPageNum);
}
else
{
setPagesAutomatic("to right");
}
}
else
{
this.addEventListener(Event.ENTER_FRAME, onEnter);
this.removeEventListener(Event.ENTER_FRAME, onEnterAutomatic);
this.completeFactor = 3;
return;
}
checkOverAutomatic = false;
prevX = 0;
prevY = 0;
destX = 0;
destY = 0;
saflip.addChildAt(pageFlipping, 5);
pageFlipping.mask = pageFlippingMask;
currentPage.mask = currentPageMask;
flipGrad.visible = true;
pageShadow.visible = true;
pageShadowBehind.visible = true;
randomFlip = Math.random() * pgH/2 - pgH/4;
automaticPageDelay -= 0.1;
automaticPageDelay = Math.max(1.2, automaticPageDelay);
}
var finishFlipping:Boolean = setCordsByAutoFlip(true);
if(finishFlipping)
{
movePages();
pagesContainer.removeChild(currentPage);
pageFlipping.mask = null;
visiblePageNumOnLeft = newVisiblePageNumOnLeft;
flipGrad.visible = false;
pageShadow.visible = false;
pageShadowBehind.visible = false;
checkOverAutomatic = true;
if(oneFlip){setPagesVisibility(true);}
else{setPagesVisibility();}
this.dispatchEvent(new PageEvent(PageEvent.PAGE_FLIPPED, direction, "NONE", visiblePageNumOnLeft));
}
else
{
movePages();
}
}
}
private function onDown(event:MouseEvent):void
{
//trace("down");
isDown = true;
cornersHolder.removeEventListener(MouseEvent.MOUSE_DOWN, onDown);
stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
}
private function onUp(event:MouseEvent):void
{
//trace("up");
canDrag = false;
autoFlip = true;
isDown = false;
if(currentCornerSprite == event.target || axis.mouseX >= pgW * 3/4)
{
flipFoward = true;
}
else
{
flipFoward = false;
}
prevX = destX = originalMouse.x;
prevY = destY = originalMouse.y;
stage.removeEventListener(MouseEvent.MOUSE_UP, onUp);
}
private function movePages():void
{
pageFlipping.rotation = flipGradMask.rotation = this.angle;
pageFlipping.x = flipGradMask.x = this.pageLocation.x;
pageFlipping.y = flipGradMask.y = this.pageLocation.y;
pageFlippingMask.rotation = currentPageMask.rotation = flipGrad.rotation =
pageShadow.rotation = pageShadowBehind.rotation = this.angle/2;
pageFlippingMask.x = currentPageMask.x = flipGrad.x = pageShadow.x =
pageShadowBehind.x = (pt1.x + pt3.x)/2;
pageFlippingMask.y = currentPageMask.y = flipGrad.y = pageShadow.y =
pageShadowBehind.y = (pt1.y + pt3.y)/2;
flipGrad.scaleX = pageFlippingMask.scaleX * Math.sqrt(originalMouse.x * originalMouse.x + originalMouse.y * originalMouse.y)/pgW;
pageShadow.scaleX = flipGrad.scaleX * .5;
pageShadowBehind.scaleX = flipGrad.scaleX * .75;
if(pageFlipping.mask == null){pageFlipping.mask = pageFlippingMask;}
if(currentPage.mask == null){currentPage.mask = currentPageMask;}
if(pageShadow.mask == null){pageShadow.mask = pageShadowMask;}
if(pageShadowBehind.mask == null){pageShadowBehind.mask = pageShadowBehindMask;}
if(pageShadowBehind.mask == null){pageShadowBehind.mask = pageShadowBehindMask;}
var gradAlpha:Number = (2*pgW - originalMouse.x)/(pgW/2)
flipGrad.alpha = pageShadow.alpha = pageShadowBehind.alpha = (originalMouse.x > 2*pgW - pgW/2) ? gradAlpha : 1;
}
private function setPagesVisibility(oneFlip:Boolean = false):void
{
var first:int;
var last:int;
//trace("before");
/*for(var k:int = 0; k < pagesVect.length; k++)
{
var pageTest:Sprite = pagesVect[k];
if(pagesContainer.contains(pageTest))
{
trace(k);
}
}*/
if(oneFlip)
{
for(var b:int = 0; b < pagesContainer.numChildren; b++)
{
if(pagesContainer.getChildAt(b) != currentPageMask)
{
pagesContainer.removeChild(pagesContainer.getChildAt(b));
}
}
first = Math.max(visiblePageNumOnLeft - (_maxPagesOverlapping - 1) * 2, 1);
last = Math.min((visiblePageNumOnLeft + 1) + (_maxPagesOverlapping - 1) * 2, pagesVect.length - 2);
}
else
{
first = Math.max(visiblePageNumOnLeft - (_maxPagesOverlapping * 2), 1);
last = Math.min((visiblePageNumOnLeft + 1) + ((_maxPagesOverlapping) * 2), pagesVect.length - 2);
}
for(var i:int = first; i <= visiblePageNumOnLeft; i += 2)
{
var page:Sprite = pagesVect[i];
page.x = 0;
if((visiblePageNumOnLeft - i)/2 >= _maxPagesOverlapping)
{
if(this.direction == "foward")
{
pagesContainer.removeChild(page);
}
}
else
{
pagesContainer.addChild(page);
}
}
for(var j:int = last; j > visiblePageNumOnLeft; j -= 2)
{
var page2:Sprite = pagesVect[j];
page2.x = pgW;
if((j - visiblePageNumOnLeft + 1)/2 > _maxPagesOverlapping)
{
if(this.direction == "backward")
{
pagesContainer.removeChild(page2);
}
}
else
{
pagesContainer.addChild(page2);
}
}
//trace("after");
//discomment to trace the pages that are rendered on the stage
/*for(k = 0; k < pagesVect.length; k++)
{
pageTest = pagesVect[k];
if(pagesContainer.contains(pageTest))
{
trace(k);
}
}*/
//trace();
}
private function checkOverCorners():Boolean
{
if(0 < this.mouseX &amp;&amp; this.mouseX < _cornerSize &amp;&amp; 0 < this.mouseY &amp;&amp; this.mouseY < _cornerSize)
{
currentCorner = "TL";
direction = "backward";
currentCornerSprite = cornersHolder.getChildAt(0) as Sprite;
if (visiblePageNumOnLeft != -1)
{
currentPage = pagesVect[visiblePageNumOnLeft];
pageFlipping = pagesVect[visiblePageNumOnLeft - 1];
pageLocation = pageTL;
translatorFunction = translateTL;
mouseOutFunction = mouseOutTL;
pageFlippingMask.scaleX = currentPageMask.scaleX = -1;
newVisiblePageNumOnLeft = visiblePageNumOnLeft - 2;
axis.x = 0; axis.y = 0; axis.scaleX = 1; axis.scaleY = 1;
return true;
}
else
{
return false;
}
}
else if(2 * pgW - _cornerSize < this.mouseX &amp;&amp; this.mouseX < 2 * pgW &amp;&amp; 0 < this.mouseY &amp;&amp; this.mouseY < _cornerSize)
{
currentCorner = "TR";
direction = "foward";
currentCornerSprite = cornersHolder.getChildAt(1) as Sprite;
if (visiblePageNumOnLeft != pagesVect.length - 1)
{
currentPage = pagesVect[visiblePageNumOnLeft + 1];
pageFlipping = pagesVect[visiblePageNumOnLeft + 2];
pageLocation = pt2;
translatorFunction = translateTR;
mouseOutFunction = mouseOutTR;
pageFlippingMask.scaleX = currentPageMask.scaleX = 1;
newVisiblePageNumOnLeft = visiblePageNumOnLeft + 2;
axis.x = 2 * pgW; axis.y = 0; axis.scaleX = -1; axis.scaleY = 1;
return true;
}
else
{
return false;
}
}
else if(2 * pgW - _cornerSize < this.mouseX &amp;&amp; this.mouseX < 2 * pgW &amp;&amp; pgH - _cornerSize < this.mouseY &amp;&amp; this.mouseY < pgH)
{
currentCorner = "DR";
direction = "foward";
currentCornerSprite = cornersHolder.getChildAt(2) as Sprite;
if (visiblePageNumOnLeft != pagesVect.length - 1)
{
currentPage = pagesVect[visiblePageNumOnLeft + 1];
pageFlipping = pagesVect[visiblePageNumOnLeft + 2];
pageLocation = pageDR;
translatorFunction = translateDR;
mouseOutFunction = mouseOutDR;
pageFlippingMask.scaleX = currentPageMask.scaleX = 1;
newVisiblePageNumOnLeft = visiblePageNumOnLeft + 2;
axis.x = 2 * pgW; axis.y = pgH; axis.scaleX = -1; axis.scaleY = -1;
return true;
}
else
{
return false;
}
}
else if(0 < this.mouseX &amp;&amp; this.mouseX < _cornerSize &amp;&amp; 2 * pgW &amp;&amp; pgH - _cornerSize < this.mouseY &amp;&amp; this.mouseY < pgH)
{
currentCorner = "DL";
direction = "backward";
currentCornerSprite = cornersHolder.getChildAt(3) as Sprite;
if (visiblePageNumOnLeft != -1)
{
currentPage = pagesVect[visiblePageNumOnLeft];
pageFlipping = pagesVect[visiblePageNumOnLeft - 1];
pageLocation = pageDL;
translatorFunction = translateDL;
mouseOutFunction = mouseOutDL;
pageFlippingMask.scaleX = currentPageMask.scaleX = -1;
newVisiblePageNumOnLeft = visiblePageNumOnLeft - 2;
axis.x = 0; axis.y = pgH; axis.scaleX = 1; axis.scaleY = -1;
return true;
}
else
{
return false;
}
}
return false;
}
private function setPagesAutomatic(direction:String):void
{
if(direction == "to right")
{
currentCorner = "NONE";
this.direction = "backward";
currentPage = pagesVect[visiblePageNumOnLeft];
pageFlipping = pagesVect[visiblePageNumOnLeft - 1];
pageLocation = pageDL;
translatorFunction = translateDL;
pageFlippingMask.scaleX = currentPageMask.scaleX = -1;
newVisiblePageNumOnLeft = visiblePageNumOnLeft - 2;
axis.x = 0; axis.y = pgH; axis.scaleX = 1; axis.scaleY = -1;
}
else
{
currentCorner = "NONE";
this.direction = "foward";
currentPage = pagesVect[visiblePageNumOnLeft + 1];
pageFlipping = pagesVect[visiblePageNumOnLeft + 2];
pageLocation = pageDR;
translatorFunction = translateDR;
pageFlippingMask.scaleX = currentPageMask.scaleX = 1;
newVisiblePageNumOnLeft = visiblePageNumOnLeft + 2;
axis.x = 2 * pgW; axis.y = pgH; axis.scaleX = -1; axis.scaleY = -1;
}
}
private function setPagesOneFlip(direction:String, pageNum:int):void
{
var i:int;
if(direction == "to right")
{
currentCorner = "NONE";
this.direction = "backward";
currentPage = pagesVect[visiblePageNumOnLeft];
pageFlipping = pagesVect[pageNum + 1];
for(i = visiblePageNumOnLeft - 2;
i >= Math.max(1, visiblePageNumOnLeft - (_maxPagesOverlapping - 1) * 2);
i -= 2)
{
pagesContainer.removeChild(pagesVect[i]);
}
if(pageNum > 0)
{
pagesContainer.addChildAt(pagesVect[pageNum], pagesContainer.getChildIndex(pagesVect[visiblePageNumOnLeft]));
}
pageLocation = pageDL;
translatorFunction = translateDL;
pageFlippingMask.scaleX = currentPageMask.scaleX = -1;
newVisiblePageNumOnLeft = pageNum;
axis.x = 0; axis.y = pgH; axis.scaleX = 1; axis.scaleY = -1;
}
else
{
currentCorner = "NONE";
this.direction = "foward";
currentPage = pagesVect[visiblePageNumOnLeft + 1];
pageFlipping = pagesVect[pageNum];
for(i = visiblePageNumOnLeft + 3;
i <= Math.min(pagesVect.length - 2, visiblePageNumOnLeft + 1 + (_maxPagesOverlapping - 1) * 2);
i += 2)
{
//trace(visiblePageNumOnLeft, pageNum, i);
if(pagesContainer.contains(pagesVect[i]))
{
pagesContainer.removeChild(pagesVect[i]);
}
}
if(pageNum < pagesVect.length - 1)
{
pagesContainer.addChildAt(pagesVect[pageNum + 1], pagesContainer.getChildIndex(pagesVect[visiblePageNumOnLeft + 1]));
}
pageLocation = pageDR;
translatorFunction = translateDR;
pageFlippingMask.scaleX = currentPageMask.scaleX = 1;
newVisiblePageNumOnLeft = pageNum;
axis.x = 2 * pgW; axis.y = pgH; axis.scaleX = -1; axis.scaleY = -1;
}
}
private function setCordsByMouse():void
{
destX += (axis.mouseX - prevX)/_pageDelay;
destY += (axis.mouseY - prevY)/_pageDelay;
prevX = destX;
prevY = destY;
var mouseXFiltered:Number = 0;
var mouseYFiltered:Number = 0;
if(destY > 0)
{
if(destX > 0)
{
mouseXFiltered = destX;
mouseYFiltered = destY;
}
else
{
mouseYFiltered = destY * pgW/(pgW - destX);
}
}
else
{
var angleTopAndMouse:Number = Math.atan2(destX - pgW, pgH - destY);
if(Math.sqrt(Math.pow(destX - pgW, 2) + Math.pow(pgH - destY, 2)) > pgDiagonal)
{
if (angleTopAndMouse <= pgDiagonalAngle &amp;&amp; angleTopAndMouse >= -pgDiagonalAngle)
{
mouseXFiltered = Math.sin(angleTopAndMouse) * pgDiagonal + pgW;
mouseYFiltered = -(Math.cos(angleTopAndMouse) * pgDiagonal - pgH);
}
else if(angleTopAndMouse > pgDiagonalAngle)
{
mouseXFiltered = destX;
}
}
else
{
mouseXFiltered = destX;
mouseYFiltered = destY;
}
}
mouseXFiltered = (mouseXFiltered < _minMouseX) ? _minMouseX : mouseXFiltered;
setPoints(mouseXFiltered, mouseYFiltered);
}
private function setCordsByAutoFlip(automatic:Boolean = false):Boolean
{
var finishFlipping:Boolean = false;
if(flipFoward)
{
if (destX > 2 * pgW - completeFactor &amp;&amp; destY < completeFactor)
{
destX = 2 * pgW;
destY = 0;
finishFlipping = true;
}
else
{
if(automatic)
{
if(destX < pgW)
{
if(oneFlip)
{
destX += (1.3 * pgW - prevX)/automaticPageDelay;
destY += (-pgH/4 - prevY)/automaticPageDelay;
}
else
{
destX += (1.7 * pgW - prevX)/automaticPageDelay;
destY += ((Math.random() * pgH/3) - prevY)/automaticPageDelay;
}
}
else
{
destX += (2 * pgW - prevX)/automaticPageDelay;
destY += (0 - prevY)/automaticPageDelay;
}
}
else
{
destX += (2 * pgW - prevX)/_pageDelay;
destY += (0 - prevY)/_pageDelay;
}
}
}
else
{
if(destX < completeFactor &amp;&amp; destY < completeFactor)
{
destX = 0;
destY = 0;
finishFlipping = true;
}
else
{
destX += (1 - prevX)/_pageDelay;
destY += (1 - prevY)/_pageDelay;
}
}
prevX = destX;
prevY = destY;
setPoints(destX, destY);
return finishFlipping;
}
private function setPoints(cordX:Number, cordY:Number):void
{
var angle:Number;
if(cordX == 0 &amp;&amp; cordY == 0)
{
angle = 0;
pageDR.x = 0;
pageDR.y = pgH;
pageDL.x = -pgW;
pageDL.y = pgH;
pageTL.x = -pgW;
pageTL.y = 0;
pt1.x = pt2.x = pt1.y = pt2.y = pt3.x = 0;
pt3.y = pgH;
}
else
{
var foldXLength:Number = (Math.pow(cordX, 2) + Math.pow(cordY, 2)) / (2 * cordX);
var foldX:Number = (foldXLength > pgW) ? pgW : foldXLength;
angle = Math.atan2(cordY, cordX - foldX);
pageDR.x = Math.cos(angle) * foldX - Math.sin(angle) * pgH + foldX;
pageDR.y = Math.sin(angle) * foldX + Math.cos(angle) * pgH;
pageDL.x = Math.cos(angle) * (foldX - pgW) - Math.sin(angle) * pgH + foldX;
pageDL.y = Math.sin(angle) * (foldX - pgW) + Math.cos(angle) * pgH;
pageTL.x = Math.cos(angle) * (foldX - pgW) + foldX;
pageTL.y = Math.sin(angle) * (foldX - pgW);
pt1.x = foldX;
pt1.y = 0;
pt2.x = Math.cos(angle) * foldX + foldX;
pt2.y = Math.sin(angle) * foldX;
if (pageDR.x <= 0)
{
pt3.x = 0;
pt3.y = pgH - (Math.pow(pgH - pageDR.y, 2) + Math.pow(-pageDR.x, 2)) / (2 * (pgH - pageDR.y));
}
else
{
pt3.x = (Math.pow(pageDR.x, 2) + Math.pow(pageDR.y - pgH, 2)) / (2 * pageDR.x);
pt3.y = pgH;
}
}
originalMouse.x = pt2.x;
originalMouse.y = pt2.y;
translatorFunction(angle);
}
private function mouseOutTL():Boolean
{
if(0 < this.mouseX &amp;&amp; this.mouseX < _cornerSize &amp;&amp; 0 < this.mouseY &amp;&amp; this.mouseY < _cornerSize)
{
return false;
}
return true;
}
private function mouseOutTR():Boolean
{
if(2 * pgW - _cornerSize < this.mouseX &amp;&amp; this.mouseX < 2 * pgW &amp;&amp; 0 < this.mouseY &amp;&amp; this.mouseY < _cornerSize)
{
return false;
}
return true;
}
private function mouseOutDR():Boolean
{
if(2 * pgW - _cornerSize < this.mouseX &amp;&amp; this.mouseX < 2 * pgW &amp;&amp; pgH - _cornerSize < this.mouseY &amp;&amp; this.mouseY < pgH)
{
return false;
}
return true;
}
private function mouseOutDL():Boolean
{
if(0 < this.mouseX &amp;&amp; this.mouseX < _cornerSize &amp;&amp; 2 * pgW &amp;&amp; pgH - _cornerSize < this.mouseY &amp;&amp; this.mouseY < pgH)
{
return false;
}
return true;
}
private function translateTL(angle:Number):void
{
this.angle = angle * 180/Math.PI;
}
private function translateTR(angle:Number):void
{
pt1.x = 2 * pgW - pt1.x;
pt2.x = 2 * pgW - pt2.x;
pt3.x = 2 * pgW - pt3.x;
this.angle = -angle * 180/Math.PI;
}
private function translateDR(angle:Number):void
{
pt1.x = 2 * pgW - pt1.x;
pt1.y = pgH - pt1.y;
pt2.x = 2 * pgW - pt2.x;
pt2.y = pgH - pt2.y;
pt3.x = 2 * pgW - pt3.x;
pt3.y = pgH - pt3.y;
this.angle = angle * 180/Math.PI;
pageLocation.x = 2 * pgW - pageLocation.x;
pageLocation.y = pgH - pageLocation.y;
}
private function translateDL(angle:Number):void
{
pt1.y = pgH - pt1.y;
pt2.y = pgH - pt2.y;
pt3.y = pgH - pt3.y;
this.angle = -angle * 180/Math.PI;
pageLocation.x = pageLocation.x;
pageLocation.y = pgH - pageLocation.y;
}
public function set cornerSize(value:Number):void
{
this._cornerSize = value;
for(var i:uint = 0; i < cornersHolder.numChildren; i++)
{
cornersHolder.getChildAt(i).width = value;
cornersHolder.getChildAt(i).height = value;
}
}
public function get cornerSize():Number
{
return this._cornerSize;
}
public function set pageDelay(value:Number):void
{
if(value < 1)
{
value = 1;
}
else if( value > 8)
{
value = 8;
}
this._pageDelay = value;
}
public function get pageDelay():Number
{
return this._pageDelay;
}
public function set minMouseX(value:Number):void
{
if(value < 0)
{
value = 0;
}
else if(value > pgW/12)
{
value = pgW/12;
}
this._minMouseX = value;
}
public function get minMouseX():Number
{
return _minMouseX;
}
public function set pageWidth(value:uint):void
{
var scaleFactor:Number = value/pgW;
this.pgW = value;
setDiagonals();
drawMasks();
drawGrads();
for(var i:uint = 0; i < pagesVect.length; i++)
{
var currentPageHolder:Sprite = pagesVect[i];
currentPageHolder.scaleX *= scaleFactor;
if(i%2 == 0 &amp;&amp; i > this.visiblePageNumOnLeft)
{
currentPageHolder.x = pgW;
}
}
cornersHolder.getChildAt(1).x = 2 * pgW;
cornersHolder.getChildAt(2).x = 2 * pgW;
}
public function get pageWidth():uint
{
return this.pgW;
}
public function set pageHeight(value:uint):void
{
var scaleFactor:Number = value/pgH;
this.pgH = value;
setDiagonals();
drawMasks();
drawGrads();
for(var i:uint = 0; i < pagesVect.length; i++)
{
var currentPageHolder:Sprite = pagesVect[i];
currentPageHolder.scaleY *= scaleFactor;
}
cornersHolder.getChildAt(2).y = pgH;
cornersHolder.getChildAt(3).y = pgH;
}
public function get pageHeight():uint
{
return this.pgH;
}
public function get currentPageNum():int
{
return visiblePageNumOnLeft;
}
override public function set width(value:Number):void
{
pageWidth = value/2;
}
override public function get width():Number
{
return pageWidth * 2;
}
override public function set height(value:Number):void
{
pageHeight = value;
}
override public function get height():Number
{
return pageHeight;
}
public function set maxPagesOverlapping(value:Number):void
{
if(value < 2) {value == 2}
else if(value > 6){value == 6;}
_maxPagesOverlapping = value;
}
public function get maxPagesOverlapping():Number
{
return _maxPagesOverlapping;
}
public function get totalPagesNum():int
{
return pagesVect.length;
}
}
}
//PageEvent Class
package
{
import flash.events.Event;
public class PageEvent extends Event
{
//dispatched when the mouse is over one of the corners
public static const MOUSE_AT_CORNER:String = "mouseAtCorner";
//dispatched when a page is flipped
public static const PAGE_FLIPPED:String = "pageFlipped";
//dispatched when the user mouses drop a page and the page is not flipped
public static const PAGE_FLIP_CANCELED:String = "pageFlipCanceled";
//possible directions: "foward" &amp; "backward"
public var direction:String;
//possible corners: "TL", "TR", "DR", "DL" &amp; "NONE", the corner will be "NONE", when the page is
//flipped automaticaly
public var corner:String;
//informs the user of the new number of the current page on left if the page is flipped. else just
//informs the previous number
public var currentPageNum:int;
public function PageEvent(type:String, direction:String, corner:String, currentPageNum:int)
{
super(type);
this.direction = direction;
this.corner = corner;
this.currentPageNum = currentPageNum
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment