首页 > 设计 > WEB开发 > 正文

12.7.在Flex Effect里使用DisplacementMapFilter过滤器

2023-07-22 12:39:19
字体:
来源:转载
供稿:网友
12.7.1 问题
你需要创建一个在图片之间置换的渐变效果。
12.7.2 解决办法
继承TweenEffect 和TweenEffectInstance 类,创建一个具有最终置换值的TweenEffect 实例,然后将这些最终置换值传给它所创建的TweenEffectInstance 类实例。在自定义的TweenEffectInstance 类里,创建一个DisplacementMapFilter 对象并且使用Flex 框架的渐变引擎通过在每个onTweenUpdate 事件上生成新的过滤器来达到预期的置换值。
12.7.3 讨论
DisplacementMapFilter 通过使用另一张图片的象素点决定变形的位置和量来置换或者变形当前图片的像素点。

置换的位置和量到设定的像素是通过置换目标图片的像素点色值决定的。

DisplacementMapFilter 的构造方法如下:
+展开
-ActionScript
public function DisplacementMapFilter(mapBitmap:BitmapData = null,
mapPoint:Point = null, componentX:uint = 0, componentY:uint = 0,
scaleX:Number = 0.0, scaleY:Number = 0.0, mode:String = "wrap",
color:uint = 0, alpha:Number = 0.0)

如此长的一行代码拆开理解较为简单:
+展开
-ActionScript
BitmapData (default = null)

这是过滤器应用到的置换目标图片或组件所用到的BitmapData 对象。
mapPoint
这个是被过滤图片的位置,对应于过滤器要应用到的置换图片的左上角位置。如果仅仅过滤图片的一部分的话,可以使用这个参数。

componentX
该参数指定作用x 位置上的图片象素颜色通道。BitmapDataChannel 定义了所有有效的常量选项值:BitmapDataChannel.BLUE 或4, BitmapDataChannel.RED 或1,BitmapDataChannel.GREEN 或2, or BitmapDataChannel.ALPHA 或8。

componentY
指定作用y 位置上的图片象素颜色通道。取值范围和componentX 的相同。

scaleX
这个参数值指定X 轴方向上的置换强度。

scaleY
这个参数值指定Y 轴方向上的置换强度。

mode
这是一个字符串,它决定怎样处理置换像素后形成的空白空间。可选值申明为DisplacementMapFilterMode 类的常量,用以显示原始的像素(mode = IGNORE)、从图片另一边封装边缘像素点(mode = WRAP,默认值)、使用最近的置换像素(mode = CLAMP)或者使用某个颜色填充这些空间(mode = COLOR)。

CustomDisplacementEffect 例示CustomDisplacementInstance。如下:
+展开
-ActionScript
package oreilly.cookbook{
import mx.effects.IEffectInstance;
import mx.effects.TweenEffect;
import mx.events.EffectEvent;
public class CustomDisplacementEffect extends TweenEffect
{
public var image:Class;
public var yToDisplace:Number;
public var xToDisplace:Number;
public function CustomDisplacementEffect(target:Object=null)
{
super(target);
this.instanceClass = CustomDisplacementInstance;
}
override protected function
initInstance(instance:IEffectInstance):void {
trace(" instance initialized ");
super.initInstance(instance);
// now that we've instantiated our instance, we can set
its properties
CustomDisplacementInstance(instance).image = image;
CustomDisplacementInstance(instance).xToDisplace =
this.xToDisplace;
CustomDisplacementInstance(instance).yToDisplace =
this.yToDisplace;
}
override public function getAffectedProperties():Array {
trace(" return all the target properties ");
return [];
}
}
}

实际上CustomDisplacementInstance 负责进行创建应用到目标的DisplacementEffect 对象。而位图对象,过滤器在DisplacementEffect 使用的,以及CustomDisplacementTween 的x 与y置换量都应用到该实例并传给DisplacementEffect。

CustomTweenEffect 创建CustomDisplacementInstance 的实例,如下:
+展开
-ActionScript
package oreilly.cookbook{
import flash.display.BitmapData;
import flash.display.BitmapDataChannel;
import flash.display.DisplayObject;
import flash.filters.DisplacementMapFilter;
import flash.filters.DisplacementMapFilterMode;
import flash.geom.Point;
import mx.effects.Tween;
import mx.effects.effectClasses.TweenEffectInstance;
public class CustomDisplacementInstance extends
TweenEffectInstance
{
public var image:Class;
public var xToDisplace:Number;
public var yToDisplace:Number;
public var filterMode:String =
DisplacementMapFilterMode.WRAP;
private var filter:DisplacementMapFilter;
private var img:DisplayObject;
private var bmd:BitmapData;
public function CustomDisplacementInstance(target:Object)
{
super(target);
}
override public function play():void {
super.play();
//make our embedded image accessible to use
img = new image();
bmd = new BitmapData(img.width, img.height, true);
//draw the actual byte data into the image
bmd.draw(img);

这个新过滤器被创建,将被设置初始状态的所有值:
+展开
-ActionScript
filter = new DisplacementMapFilter(bmd, new
Point(DisplayObject(target).wi
dth/2 - (img.width/2), DisplayObject(target).height/2 -
(img.height/2))),
BitmapDataChannel.RED, BitmapDataChannel.RED, 0, 0,
filterMode, 0.0, 1.0);
//copy any filters already exisiting on the target so
that we don't
destroy them when we add our new filter
var targetFilters:Array = (target as
DisplayObject).filters;
targetFilters.push(filter);
//set the actual filter onto the target
(target as DisplayObject).filters = targetFilters;
//create a tween that will begin to generate the next
values of each frame of our effect
this.tween = new Tween(this, [0, 0], [xToDisplace,
yToDisplace],
duration);
}

该类的很多繁重工作都在setDisplacementFilter 中完成。因为过滤器是累积的(它们是叠加应用的),前面的DisplacementMapFilter 必须移除。这需要通过循环遍历目标对象的过滤器数组来完成,移除所有DisplacementMapFilter 的实例。然后使用Tween 传过来的值创建一个新的过滤器并且将此过滤器应用到目标对象上。注意要让过滤器适当的显示,过滤器数组必须要重置。使用Array.push 方法添加过滤器到数组中不会引起目标DisplayObject 使用过滤器重绘。
+展开
-ActionScript
private function setDisplacementFilter(displacement:Object):void{
var filters:Array = target.filters;
// Remove any existing Displacement filter to ensure that
ours is the only one
var n:int = filters.length;
for (var i:int = 0; i < n; i++) {
if (filters[i] is DisplacementMapFilter)
filters.splice(i, 1);
}
//create the new filter with the values passed in from
the tween
filter = new DisplacementMapFilter(bmd, new Point(0, 0),
BitmapDataChannel.RED, BitmapDataChannel.RED,
displacement[0] as Number, displacement[1] as
Number, filterMode, 0.0, 0);
//add the filter to the filters on the target
filters.push(filter);
target.filters = filters;
}
//each time we're ready to update, re-create the
displacement map filter
override public function onTweenUpdate(value:Object):void
{
setDisplacementFilter(value);
}
//set the filter one last time and then dispatch the tween
end event
override public function onTweenEnd(value:Object):void
{
setDisplacementFilter(value);
super.onTweenEnd(value);
}
}
}

当渐变结束时,DisplacementMapFilter 的最终值用来设置目标DisplayObject 的最终外观,同时调用TweenEffectInstance 类的onTweenEnd 方法。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表