这几天在做的一个项目需要做一个卡片翻转效果,实践了一下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;
}
}
}
}
}
下载源文件 (source)