⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pageflip.as

📁 as3.0 翻书效果
💻 AS
字号:
package crlclr.flip {
	
	import flash.geom.Point;
	import flash.display.BitmapData;
	import flash.geom.Matrix;
	import flash.display.Shape;
	
	public class PageFlip {
	
		public static function computeFlip(ptd:Point,pt:Point,pw:int,ph:int,ish:Boolean,sens:int):Object{

			// useful vars
			var dfx:Number=ptd.x-pw*pt.x;
			var dfy:Number=ptd.y-ph*pt.y;
			var spt:Point=pt.clone();
			var opw:int=pw;
			var oph:int=ph;
		
			// offset corections
			var temp:Number;

			// transform matrix 
			var mat:Matrix=new Matrix();

			if (!ish){
				// size
				temp=pw;
				pw=ph;
				ph=temp;

				// ptd
				temp=ptd.x;
				ptd.x=ptd.y;
				ptd.y=temp;

				// pt
				temp=pt.x;
				spt.x=pt.y;
				spt.y=temp;
			}

			//	pt1 & pt2 are the two fixed points of the sheet. opposed to ptd drag one.
			var pt1:Point=new Point(0,0);
			var pt2:Point=new Point(0,ph);

			// default points array
			// cPoints -> the fliped part
			var cPoints:Array=[null,null,null,null];
			// pPoints -> the fixed part
			var pPoints:Array=[new Point(0,0),new Point(pw,0),null,null,new Point(0,ph)];

			// compute some flip
			flipDrag(ptd,spt,pw,ph);

			// ditstance 
			// it allows you to have a valid position for ptd.
			// the limit is the diagonal of the sheet here
			limitPoint(ptd,pt1,(pw*pw+ph*ph)*sens);
			// the limit is about the opposite fixed point
			limitPoint(ptd,pt2,(pw*pw)*sens);

			// first fliped point
			cPoints[0]=new Point(ptd.x,ptd.y);

			var dy:Number=pt2.y-ptd.y;
			var tot:Number=pw-ptd.x-pt1.x;
			var drx:Number=getDx(dy,tot);

			// fliped angle
			var theta:Number=Math.atan2(dy,drx);
			if (dy==0)theta=0;

			// another fliped angle
			var beta:Number=Math.PI/2-theta;
			var hyp:Number=(pw-cPoints[0].x)/Math.cos(beta);
		
			// vhyp is the hypotenuse of the fliped part
			var vhyp:Number=hyp;
			// if hyp is greater than the height of the sheet or hyp is 
			// negative, the fliped part has 4 points
			// else, it's just a 3 points part (simple corner).
			if (hyp>ph || hyp<0)vhyp=ph;
				
			// second fliped point
			cPoints[1]=new Point(	cPoints[0].x+Math.cos(-beta)*vhyp,
								cPoints[0].y+Math.sin(-beta)*vhyp);

			// last fliped point
			cPoints[3]=new Point(cPoints[0].x+drx,pt2.y);
			
			// if we have a 4 points shape
			if (hyp!=vhyp){
				dy=pt1.y-cPoints[1].y;
				tot=pw-cPoints[1].x;
				drx=getDx(dy,tot);

				// push the before the last point
				cPoints[2]=new Point(cPoints[1].x+drx,pt1.y);	

				// we can now find the fixed points of the sheet
				pPoints[1]=cPoints[2].clone();
				pPoints[2]=cPoints[3].clone();
				pPoints.splice(3,1);
			}else{
				// else we delete the point
				cPoints.splice(2,1);

				// we can now find the fixed points of the sheet
				pPoints[2]=cPoints[1].clone();
				pPoints[3]=cPoints[2].clone();
			}

			// these two polygons are always convex !

			// now we can flip the two arrays
			flipPoints(cPoints,spt,pw,ph);
			flipPoints(pPoints,spt,pw,ph);

			// if !ish (vertical mode)
			// we have to change the points orientation 
			if (!ish){
				oriPoints(cPoints,spt,pw,ph);
				oriPoints(pPoints,spt,pw,ph);
			}

			// flipped part transfrom matrix
			
			var gama:Number=theta;
			
			if (pt.y==0)gama=-gama;
			if (pt.x==0)gama=Math.PI+Math.PI-gama;
			if (!ish)gama=Math.PI-gama;

			mat.a=Math.cos(gama);
			mat.b=Math.sin(gama);
			mat.c=-Math.sin(gama);
			mat.d=Math.cos(gama);

			ordMatrix(mat,spt,opw,oph,ish,cPoints,pPoints,gama,beta);

			// here we fix some mathematical bugs or instabilities
			if (vhyp==0)cPoints=null;
			if (Math.abs(dfx)<1 && Math.abs(dfy)<1)cPoints=null;

			// now we just have to return all the stuff
			return {cPoints:cPoints,pPoints:pPoints,matrix:mat,width:opw,height:oph};
		}

		public static function drawBitmapSheet(ocf:Object,mc:Shape,bmp0:BitmapData,bmp1:BitmapData):void{

			
			var wid:Number=ocf.width;
			var hei:Number=ocf.height;
			var nb:Number;
			var ppts:Array=ocf.pPoints;
			var cpts:Array=ocf.cPoints;


			mc.graphics.clear();
			mc.graphics.beginBitmapFill(bmp0,new Matrix(),false,true);
			nb=ppts.length;
			mc.graphics.moveTo(ppts[nb-1].x,ppts[nb-1].y);
			while (--nb>=0)mc.graphics.lineTo(ppts[nb].x,ppts[nb].y);
			mc.graphics.endFill();

			if (cpts==null)return;

			mc.graphics.beginBitmapFill(bmp1,ocf.matrix,false,true);
			nb=cpts.length;
			mc.graphics.moveTo(cpts[nb-1].x,cpts[nb-1].y);
			while (--nb>=0)mc.graphics.lineTo(cpts[nb].x,cpts[nb].y);
			mc.graphics.endFill();

		}

		private static function oriPoints(pts:Array,po:Point,pw:Number,ph:Number):void{
			
			var nb:Number=pts.length;
			var temp:Number;

			while (--nb>=0){
				temp=pts[nb].x;
				pts[nb].x=pts[nb].y;
				pts[nb].y=temp;
			}
		}

		/**
		*	ptdarg correction
		*/
		private static function flipDrag(ptd:Point,po:Point,pw:Number,ph:Number):void{

			// flip y
			if (po.y==0)ptd.y=ph-ptd.y;

			// flip x
			if (po.x==0)ptd.x=pw-ptd.x;

		}

		/**
		*	flip correction
		*/
		private static function flipPoints(pts:Array,po:Point,pw:Number,ph:Number):void{
		
			var nb:Number=pts.length;
			// flip
			if (po.y==0 || po.x==0){
				while (--nb>=0){
					if (po.y==0)pts[nb].y=ph-pts[nb].y;
					if (po.x==0)pts[nb].x=pw-pts[nb].x;
				}
			}
		}

		private static function getDx(dy:Number,tot:Number):Number{
			return (tot*tot-dy*dy)/(tot*2);
		}

		private static function limitPoint(ptd:Point,pt:Point,dsquare:Number):void{

			var theta:Number;
			var lim:Number;

			var dy:Number=ptd.y-pt.y;
			var dx:Number=ptd.x-pt.x;

			var dis:Number=dx*dx+dy*dy;

			// we save some times using square
			if (dis>dsquare){
				theta=Math.atan2(dy,dx);
				lim=Math.sqrt(dsquare);
				ptd.x=pt.x+Math.cos(theta)*lim;
				ptd.y=pt.y+Math.sin(theta)*lim;
			}
		}

		/**
		*	matric correction
		*
		*/
		private static function ordMatrix(mat:Matrix,spt:Point,opw:Number,oph:Number,ish:Boolean,cPoints:Array,pPoint:Array,gama:Number,beta:Number):void{

			if (spt.x==1 && spt.y==0){
				mat.tx=cPoints[0].x;
				mat.ty=cPoints[0].y;
				if (!ish){
					mat.tx=cPoints[0].x-Math.cos(gama)*opw-Math.cos(-beta)*oph;
					mat.ty=cPoints[0].y-Math.sin(gama)*opw-Math.sin(-beta)*oph;
				}
			}

			if (spt.x==1 && spt.y==1){
				mat.tx=cPoints[0].x+Math.cos(-beta)*oph;
				mat.ty=cPoints[0].y+Math.sin(-beta)*oph;
				if (!ish){
					mat.tx=cPoints[0].x+Math.cos(-beta)*oph;
					mat.ty=cPoints[0].y-Math.sin(-beta)*oph;
				}
			}

			if (spt.x==0 && spt.y==0){
				mat.tx=cPoints[0].x-Math.cos(gama)*opw;
				mat.ty=cPoints[0].y-Math.sin(gama)*opw;
			}

			if (spt.x==0 && spt.y==1){
				mat.tx=cPoints[0].x-Math.cos(gama)*opw-Math.cos(-beta)*oph;
				mat.ty=cPoints[0].y-Math.sin(gama)*opw+Math.sin(-beta)*oph;
				if (!ish){
					mat.tx=cPoints[0].x;
					mat.ty=cPoints[0].y;
				}
			}
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -