05. 03. 09
[Flash10+3D] 简单的、清晰的卡片翻转效果
这几天在做的一个项目需要做一个卡片翻转效果,实践了一下Flash 10的新的3D功能。果真是方便至极,所有的可视化对象现在都有了3D相关的属性,只需要设置rotationY变化,就可以做出很炫的翻转效果了。但是我发现,经过3D变换后的对象,都会被Flash转成位图缓存的方式显示,这样原先清晰的一些文字、图片等内容,就会显得比较模糊,演示:(需要安装 Adobe Flash Player 10 才能看到效果)
第一面的文字本来是清晰的,翻转一遍之后就模糊了。Google了好久都没有找到解决方案,抓狂。。后来突然想到,是不是可以这样,将要变回清晰的对象换个清晰的父对象?实验了一下,果然可行,大喜!好像我太out了吧,直觉告诉我,在Flash9+Papervision3D的年代,大家应该都已经知道这个方法的了,但是我确实没有找到……现在将代码重新整理了一遍,记录下来,也许对大家有所帮助。
先看看效果:
主要的类:
/** * * @author qhwa, , qhwa@163.com * This class is a sample of Flash-10-3D-flipping, * that can keep faces clear, not as fuzzy as * default. * * 这个类演示了如何使用Flash10自带的3D功能创建一个 * 简单的卡片翻转效果,同时保持文字和其他内容的 * 清晰 * */ package qhwa.twosideflip { import flash.display.DisplayObject; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.text.TextField; import flash.text.TextFieldType; import gs.easing.Back; import gs.TweenLite; /** * ... * @author ... */ public class Card extends Sprite { [Embed(source='../../../lib/goodbyewow02.jpg')] private var FrontFace:Class; [Embed(source='../../../lib/goodbyewow04.jpg')] private var BackFace:Class; private var fFace:Sprite; private var bFace:Sprite; private var cleanObj:Sprite; private var dirtyObj:Sprite; public function Card() { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); // entry point var frontBg:DisplayObject = new FrontFace(); var backBg:DisplayObject = new BackFace(); frontBg.x = backBg.x = - frontBg.width / 2; frontBg.y = backBg.y = - frontBg.height / 2; fFace = new Sprite(); bFace = new Sprite(); fFace.addChild(frontBg); bFace.addChild(backBg); //背面需要额外处理一下, //翻转过来,并且暂时隐藏 bFace.scaleX *= -1; bFace.visible = false; bFace.buttonMode = fFace.buttonMode = true; //测试的文字 var testTF:TextField = new TextField(); testTF.width = 400; testTF.height = 200; testTF.textColor = 0xFFFFFF; testTF.htmlText = "验证码是防止被机器人恶意灌水的一个方法,"+ "产生一个只有服务器才知道的信息(例如一个单词、数字等)," + "在客户端浏览器中以机器人不能分析的方式(通常是图片)出现," + "作为判断机器人和真人的一个依据。一般是在服务器端生成图片," + "由用户在文本框输入看到的文字。"; testTF.appendText(testTF.text); testTF.selectable = true; testTF.multiline = true; testTF.wordWrap = true; testTF.x = frontBg.x + 10; testTF.y = frontBg.y + 200; testTF.type = TextFieldType.INPUT; fFace.addChild(testTF); cleanObj = new Sprite(); dirtyObj = new Sprite(); dirtyObj.addChild(fFace); dirtyObj.addChild(bFace); addChild(dirtyObj); addChild(cleanObj); addEventListener(MouseEvent.CLICK, clickHandler); } private function clickHandler(e:MouseEvent = null):void { // 修改文字时不动 if (e.target is TextField) return; if (e.target == fFace || e.target.parent == fFace) { // flip to back dirty(); TweenLite.killTweensOf(dirtyObj); TweenLite.to( dirtyObj, 1, { rotationY:180, ease: Back.easeOut, onComplete: cleanBackFace, onUpdate: update } ); } else if (e.target == bFace || e.target.parent == bFace) { // flip to front dirty(); TweenLite.killTweensOf(dirtyObj); TweenLite.to( dirtyObj, 1, { rotationY:0, ease: Back.easeOut, onComplete: cleanFrontFace, onUpdate: update } ); } } /** * 检查应该显示哪个面 */ private function update():void { bFace.visible = dirtyObj.rotationY > 90 && dirtyObj.rotationY < 270; fFace.visible = !bFace.visible; } /** * 清晰化封面 */ private function cleanFrontFace():void { if (dirtyObj.contains(fFace)) { dirtyObj.removeChild(fFace); cleanObj.addChild(fFace); } } /** * 清晰化背面 */ private function cleanBackFace():void { if (dirtyObj.contains(bFace)) { dirtyObj.removeChild(bFace); cleanObj.addChild(bFace); bFace.scaleX *= -1; } } /** * 封面和背面都放入dirty容器,进行旋转操作 */ private function dirty():void { if (cleanObj.contains(fFace) || cleanObj.contains(bFace)) { var face:DisplayObject = cleanObj.getChildAt(0); cleanObj.removeChild(face); dirtyObj.addChild(face); if (face == fFace) { dirtyObj.swapChildren(face, bFace); } else { bFace.scaleX *= -1; } } } } }
In: - Flash -
>我试用了你的方法,但是失败了。
可能是 TweenLite 還沒跑完吧~~
用個 Timer 延遲檢查 Matrix3D 是否成功被設為 null
我笨的过^
这个下载了,不知道怎么用,那个xml文件怎么导入的?
我提示,xml is a reserved identifier
@cityflying, 需要用FlashDevelop打开项目(.as3proj) 文件
这里没有用到xml哦。你的提示的意思是,XML是一个保留的关键字,不能用作变量名。
@Ticore, thanks, 我再研究一下