AS3 Bitmap folding with DrawTriangles.
Tags: As3 Bitmap folding, Drawtriangles, Flash Page Flipping, AS3 uvtData, beginBitmapFill, drawPath.
BitmapFold uses the latest AS3 DrawTriangles and DrawPath features along with 4 small custom functions to find the intersections and vertices points in order to fold a bitmap image. Unlike other page flip examples, this one does not use any flash rotation, masking or tweening, just pure AS3 code.
FRAME 2 Functions:

PointOnHypotenuse(pt1,pt2,newpt,distance) Point.interpolate but uses pixel distance, can also extend line.
  pt1:Point — The starting xy coordinate of the line.
  pt2:Point — The ending xy coordinate of the line.&
  newpt:Object — The Object to move to location on line.
  distance:Number — distance form pt1 to place newpt.

rightAnglePt(pt1,pt2,pt3,newpt,distance,norm) a right-angle line from pt3 on the line to distance.
  pt1:Object — Uses object's coordinate to start a line.
  pt2:Object — Uses object's coordinate to end a line.
  pt3:Object — A line to start from (usually pt1 or pt2 or a value from PointOnHypotenuse).
  newpt:Object — places third object right-angled from pt.
  distance:Number — distance in pixels to place newpt from pt3.
  norm:int (default=0) — 0 for right-hand normal or 1 for left-hand normal (opposite direction).

PointToLine(pt1,pt2,pt,newpt) a right-angle line from pt3 to the line.
  pt1:Object — Uses object's coordinate to start a line.
  pt2:Object — Uses object's coordinate to end a line.
  pt3:Object — Uses third object's coordinate (anywhere away from pt1 and pt2).
  newpt:Object — The Object to place right-angled on the line from pt3.

Intersection(pt1,pt2,pt3,pt4) returns the intersection point of two lines
  pt1:Point — The starting xy coordinate of first line.
  pt2:Point — The ending xy coordinate of first line.
  pt3:Point — The starting xy coordinate of second line.
  pt4:Point — The ending xy coordinate of second line.
How the code works:

var A:Point = new Point(page.x,page.y);
var B:Point = new Point(A.x+bmpWidth,A.y);
var C:Point = new Point(B.x,A.y+bmpHeight);
var D:Point = new Point(A.x,C.y);

 

top left page.
top right page.
bottom right page.
bottom left page.

var midpt:Point = Point.interpolate(A,mouse,.5);
rightAnglePt(A,mouse,midpt,N,1,1)

var AB:Point=Intersection(midpt,N,A,B);
var BC:Point=Intersection(midpt,N,B,C);
var CD:Point=Intersection(midpt,N,C,D);
var DA:Point=Intersection(midpt,N,D,A);

center of drag line from A.
N = Normal right angle.

Get page's rectangle
intersection points
DA and AB.
 

The Intersection of points AB, BC, CD and DA
will expand pass the corners.  The four functions in frame 2 now gives you multiple choices as to
how to place the page nodes 1, 2, 3 and 4.

You could add four more symbols to the stage.
Call them ABnode, BCnode, CDnode & DAnode
then add ABnode.x=Ab.x; ABnode.y=AB.y; etc.
in the foldpage function to see them in action.

The red dot (node3)
can be positioned by the
rightAnglePt function.
pt1 (DA) to pt2 (Mouse).
pt3 (Mouse) to distance
of image width or use PointOnHypotenuse
Mouse (pt1) to AB (pt2),
newpt (node3) to distance
of image width.

drawTriangles uvtData in frame 3 explained:
One triangle page curl

vertices.push(mouse.x,mouse.y,node1.x,node1.y,node2.x,node2.y);
indices.push(0,1,2);
uvtData.push(1,0, 1,n1Ay, Bxn2,0);

vertices: from mouse go clock-wise to node 1 then node 2.
indices: start at mouse (0) then node1 (1) then node2 (2).
uvtData:
start position: x=1 top right corner, y=0 top of image.
next position: x=1 width of image,  y=node1.y to Corner A.
next position: x=Corner B to node2.x, y=0 top of image.
 

Our page curl is the opposite page corner so we start on the right-hand corner of the back page.

flashmath.com has an excellent explanation of uvtData. Rather than me repeat it, please go to the link below.
The drawTriangles Method in Flash Player 10 for 2D Image Transformations  flashandmath.com

How we find our uvtData at the page's intersections (the folded corners):
A uvtData edge is measure from 0-1 (normalize vector 0-1).
We can easily find a fold point between 0-1 by dividing our distance by the images width or height.
Sometimes we have to get our distances for left to right or right to left, top to bottom or bottom to top.

A.x is the same value as D.x horizontally B.x is the same value as C.x horizontally
var Bxn2=(B.x-node2.x)/bmpWidth;
var n1Ay=(node1.y-A.y)/bmpHeight;
var n2Ay=(node2.y-A.y)/bmpHeight;
var n1Ax=(node1.x-A.x)/bmpWidth;
var Bxn1=(B.x-node1.x)/bmpWidth;
width normalized 1-0 for uvtData.
height normalized 0-1 for uvtData.
short rightside normalized 0-1 for uvtData.
short bottomside normalized 0-1 for uvtData.
short bottomside normalized 1-0 for uvtData.
Once we pass over a page edge we add more triangle. Starting at the mouse position we go clock-wise around the outer edge of all triangles (not each triangle) to find the uvtData (being reversed it can get tricky).
Sticky Note bitmap fold. FLASH CS4 Profeesssional - ActionScript 3.

Files:
BitmapFold.fla //FLASH CS4
BitmapFold.swf //compliled CS4
page1.jpg, page2.jpg, page3.jpg, page4.jpg, page5.jpg //public domain images
BitmapFold.htm //generated flash html page.

For CS3 Programmers: all code is commented within the fla and is a good learning experience for medium to advanced AS3 programmers.

How to setup:
Add three or more images in the same directory folder of the BitmapFold.swf file.

Requires a minimum of three (3) images (base, front and back pages).
  1.  Open fla in FLASH CS4.
  2.  Click TIMELINE actions in FRAME 1.
  3.  See third line of ACTIONS - reads as follows:
  4. var imagePath:Array = ["page1.jpg","page2.jpg","page3.jpg","page4.jpg","page5.jpg"]; //minimum 3 images!
  5. You only need to change this line to have at least three or more of your own images.

Example using 4 images:
var imagePath:Array = ["myimage.jpg","dog.jpg","cat.jpg","04.jpg"]; //minimum 3 images!

All images must be the same size.
Put Image name in double quotes separated by comma (no comma after last image).

DO NOT CHANGE ANY CODE UNLESS:

You want a different drop page effect in frame 1

var timer1:Timer=new Timer(36,36);
function Timer1Start(e:TimerEvent):void {newBitmap.rotationY += 10; newBitmap.y -= 20;}

You can add more timers (each would require TimerEvent.TIMER and TimerEvent.TIMER_COMPLETE listeners).
HOWEVER, the last timer needs the shuffle card routine which is currently in Timer1Finished(e:TimerEvent).

for (var i=1;i<=shuffle.length-2;i++){shuffle.unshift(shuffle.pop());} //this tracks the cards order of display.

The DropShadowFilter effect on Lines 2 through 7 can be removed in frame 3.
DO NOT REMOVE ANY Stop() commands from line 1.

FINALLY for your own reference the Stage instance names are:

  1. A checkbox instance named 'CheckBox1' and another named 'CheckBox2'.
  2. A 20Χ20 yellow box on stage instance named 'corner'.
  3. A stage symbol named 'page' (it’s a container with nothing in it and is where your images will be display).
  4. Four 15Χ15 circles on stage symbols named ‘note1, node2, node3 and node4.
  5. A dynamic text box called 'angletext'.

Robert W. Stewart

Other Flash CS4 Basic Tutorials:
The new drawPath Method in Flash CS4  flashandmath.com

1