您的位置:首页 > 其它

flash特效原理:图片滑动放大效果(3)

2010-02-28 13:48 453 查看


在之前制作的版本,由于没有引入缓冲的效果,看起来效果并不好,这一次修改一下,把之前的改造一下。有了缓冲的帮助,效果完善了很多

但是还是有内存的一些问题,让人觉得不爽。

改进办法,对每一张图片加入Event。EnterFrame 事件,每一帧刷新,这样的好处使动画变得连贯,但是不好的地方会导致内存使用过多

使用的时候需要特别小心。这次加入补间引擎结合,发觉效果真的不错。使用Tweener 作为补间使用,可以自己去下载测试。

基础类并没有改变

package com.image
{
//特效类当中基本参数
public class Effect
{
private var Ratio:Number;//缩放比率
private var Max:Number;//设置最大缩放比率
private var Distans:Number;//图片距离
public function Effect()
{

}

//设置总的属性值
public function setPorperty(maxValue:Number=0,radioValue:Number=0,distanceValue:Number=0):void
{
this.max=maxValue;
this.ratio=radioValue;
this.distance=distanceValue;
}

//设置最大的缩放比率
public function set max(value:Number):void
{
Max=value;
}
public function get max():Number
{
return Max;
}
//设置鼠标与图片之间距离的差的绝对值的缩放比率
public function set ratio(value:Number):void
{
Ratio=value;
}
//设置鼠标与图片之间距离的差的绝对值的缩放比率
public function get ratio():Number
{
return Ratio;
}

//设置图片之间的距离
public function set distance(value:Number):void
{
Distans=value;
}
public function get distance():Number
{
return Distans;
}
}
}


对RollPhoto进行改造。这个只是对X轴生效,暂时没有考虑到Y轴时候,日后会进行第四版本改造,离实用性还是差一定距离,日后有能力会继续延伸。

在这里类,加入补间应用。

package com.image
{
//图片滑动效果version 3.0
//加入缓冲效果 写于2010年2月27日

import flash.display.Stage;
import caurina.transitions.*;
import flash.geom.*;
import flash.events.*;
import flash.display.MovieClip;

public class RollPhoto extends Effect
{
private var mystage:Stage;//舞台
private var Arraylength:int;
private var ImageWidth:Number;
private var list:Array;//图片阵列
private var contain:MovieClip=new MovieClip();
private var key1:Boolean=false;
private var key2:Boolean=true;
private var h:Number;
public function RollPhoto(stage:Stage)
{
stage.addChild(contain);
this.mystage=stage;

}
//对每一张图片实现监听
public function ActionListener(array:Array,h:Number=0):void
{
Arraylength=array.length;
ImageWidth=array[0].width;
list=array;
this.h=h;
for (var i:uint=0; i<array.length; i++)
{
contain.addChild(array[i]);
array[i].pos=array[i].x;//记录位置
}
mystage.addEventListener(MouseEvent.MOUSE_MOVE,onOverHandler);
}

//执行监听
private function doAction():void
{
for (var i:uint=0; i<list.length; i++)
{
list[i].addEventListener(Event.ENTER_FRAME,Run);
}
}
//取消监听事件
private function CancalAction():void
{
for (var i:uint=0; i<list.length; i++)
{
list[i].removeEventListener(Event.ENTER_FRAME,Run);
}

}
private function onOverHandler(event:MouseEvent):void
{
if (contain.hitTestPoint(mystage.mouseX,mystage.mouseY)&&mystage.mouseY<list[0].y+h)
{
key1=true;
if (key2)
{
doAction();
key2=false;
}
}
else
{
if (key1)
{
for (var i:uint=0; i<list.length; i++)
{
Tweener.addTween(list[i],{scaleX:1,scaleY:1,time:0.5, transition:"easeOut"});
Tweener.addTween(list[i],{x:list[i].pos,time:0.5, transition:"easeOut"});
}
CancalAction();
key2=true;
key1=false;
}
}
}

private function Run(event:Event):void
{
if (key1)
{
var s:Number=super.max-Math.abs(mystage.mouseX-event.currentTarget.x)*super.ratio;//公式
if (s<1)
{
zoomEffect(event.currentTarget as MovieClip,1);
}
else
{
zoomEffect(event.currentTarget as MovieClip,s);
resetPosition(list);
}
}

}
//放大
private function zoomEffect(mc:MovieClip, scale:Number):void
{
var ratio:Number = 0.4;
mc.scaleX = mc.scaleY += (scale-mc.scaleX)*ratio;
}

//复位
private function resetPosition(array:Array):void
{
for (var i:uint=1; i<array.length; i++)
{
array[i].x = array[i-1].x+array[i-1].width+super.distance;
}
}

}
}


这次代码和上次没有发生很多改变,仅仅只是改变了RollPhoto类。

myphoto.ActionListener(array,-array[0].height/2);//初始化监听

只是添加了这个。

制作这个demo过程:先外部加载图片,然后采取数组和容器管理,对每一张实现帧循环,这样动画会流畅很多,带来效果同时,如果不释放掉内存就引起内存不断增大,因此目前这个demo 只能是看,实用还没达到。

其他可以参考flash特效原理:图片滑动放大效果(1)(2)

在检测碰撞的时候,缓冲动画会一直在计算,导致内存增大其中原因之一。在设计的时候,有意在不监听的时候去除监听事件,这样会处理一部分内存,不知道有无更加好方案,或者这个设计方案一开始就存在缺陷。真的暂时还没解决到。

下面是一些代码清单,有兴趣可以玩啊。不过内存吃掉你的机器不要怪我 哈哈

package
{
import flash.display.MovieClip;
import flash.events.*;
import flash.geom.*;
import flash.system.*;
import flash.text.*;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.display.DisplayObject;
import flash.display.Loader;
import flash.net.*;
import com.image.RollPhoto;
import com.image.Reflect;
import com.image.tool.Contain;

public class Main extends MovieClip
{
private var array:Array= new Array();//用于管理的数组
private var list:MovieClip=new MovieClip();//图片容器
private var myphoto:RollPhoto;//图片滚动对象
private var count:int=0;//图片加载的计数器
private var imageList:Array=new Array();

public function Main()
{
init();
}
private function init():void
{
myphoto=new RollPhoto(stage);//初始化对象
myphoto.setPorperty(1.8,0.0025,8);//设置属性
addEventListener(Event.ENTER_FRAME,Run);
addImages("./image/1.png","./image/2.png","./image/3.png","./image/4.png","./image/5.png","./image/6.png","./image/7.png","./image/7.png","./image/7.png");//外部加载图片
addChild(list);
list.y=60;
list.x=60;

}
//创建列表物体
private function createObj(images:Array):void
{

for (var i:uint=0; i<images.length; i++)
{
var bit:MovieClip=new MovieClip();//空白影片剪辑
bit.addChild(images[i]);
bit.buttonMode=true;
bit.x=i*(bit.width+8);
bit.y=150;
var r1:Reflect = new Reflect({mc:bit, alpha:30, ratio:60, distance:0, updateTime:-1, reflectionDropoff:0});
array.push(bit);//数组管理
list.addChild(bit);//容器管理
Contain.RegPoint(bit,new Point(0,bit.height));//重新更改注册点
bit.addEventListener(MouseEvent.MOUSE_DOWN,mouseDownHandler);
}

myphoto.ActionListener(array,-array[0].height/2);//初始化监听

}

private function Run(event:Event):void
{
memory.text=String(System.totalMemory/1024)+"/kb";//内存监控
}

private function mouseDownHandler(event:MouseEvent):void
{
trace(event.currentTarget);
}
//加载外部图片
private function addImages(...args):void
{
count=args.length;
for(var i:int=0;i<args.length;i++)
{
var loader:Loader=new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onComplete);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,onError);
loader.load(new URLRequest(args[i]));
}
}
private function onComplete(event:Event):void
{
var bitmap:Bitmap=event.currentTarget.content as Bitmap;
imageList.push(bitmap);
event.currentTarget.removeEventListener(Event.COMPLETE,onComplete);
count--;
if(count==0)
{
trace(imageList.length);
createObj(imageList);
}

}
private function onError(event:Event):void
{
throw new Error("路径错误");
}

}
}


下载第三版本测试demo:





存在性能问题:依旧有待去解决

第二种办法:内存会减少一些,只实现一个EnterFrame事件

配合MouseEvent.MOUSE_MOVE 事件实现。可以自己测试一下。

为每一张图片都安装上EnterFrame 事件,他可以在每一帧刷新的时候执行,呈现同步的过程

优点:动画效果更加好,缺点内存不断消耗,进行一些不好的运算

只是在一帧的情况使用for循环。对每一张图片进行缩放和位置定位,会出现到先后的顺序。

function Run(e:Event):void

{

for(i)

{

//执行行为

}

}

这种情况出现是动画不流畅,但是内存没有那么大。

总的来讲,这个demo 还没算好,离应用还是有很多距离。内存使用问题没解决好。盼望日后会继续跟踪这个问题。

package com.image
{
//图片滑动效果version 4.0
//加入缓冲效果 写于2010年3月1日

import flash.display.Stage;
import caurina.transitions.*;
import flash.geom.*;
import flash.events.*;
import flash.display.MovieClip;

public class RollPhoto extends Effect
{
private var mystage:Stage;//舞台
private var Arraylength:int;
private var ImageWidth:Number;
private var list:Array;//图片阵列
private var contain:MovieClip=new MovieClip();
private var key1:Boolean=false;
private var key2:Boolean=true;
private var h:Number;
public function RollPhoto(stage:Stage)
{
stage.addChild(contain);
this.mystage=stage;
}
//对每一张图片实现监听
public function ActionListener(array:Array,h:Number=0):void
{
Arraylength=array.length;
ImageWidth=array[0].width;
list=array;
this.h=h;
for (var i:uint=0; i<array.length; i++)
{
contain.addChild(array[i]);
array[i].pos=array[i].x;//记录位置
}
mystage.addEventListener(MouseEvent.MOUSE_MOVE,onOverHandler);
}
//执行监听
private function doAction():void
{
mystage.addEventListener(Event.ENTER_FRAME,Run);
}
//取消监听事件
private function CancalAction():void
{
mystage.removeEventListener(Event.ENTER_FRAME,Run);
}
private function onOverHandler(event:MouseEvent):void
{
if (contain.hitTestPoint(mystage.mouseX,mystage.mouseY)&&mystage.mouseY<list[0].y+h)
{
key1=true;
if (key2)
{
doAction();
key2=false;
}
}
else
{
if (key1)
{
for (var i:uint=0; i<list.length; i++)
{
Tweener.addTween(list[i],{scaleX:1,scaleY:1,time:0.5, transition:"easeOut"});
Tweener.addTween(list[i],{x:list[i].pos,time:0.5, transition:"easeOut"});
}
CancalAction();
key2=true;
key1=false;
}
}
}
private function Run(event:Event):void
{
if (key1)
{
MakeEffect(list);
}

}
//产生效果
private function MakeEffect(array:Array):void
{
for (var i:uint=0; i<array.length; i++)
{
var s:Number=super.max-Math.abs(mystage.mouseX-array[i].x)*super.ratio;//公式
if (s<1)
{
zoomEffect(array[i],1);
}
else
{
zoomEffect(array[i],s);
resetPosition(list);
}
}

}
//放大
private function zoomEffect(mc:MovieClip, scale:Number):void
{
Tweener.addTween(mc,{scaleX:scale,scaleY:scale,time:0.5, transition:"easeOut"});
}
//复位
private function resetPosition(array:Array):void
{
for (var i:uint=1; i<array.length; i++)
{
Tweener.addTween(array[i],{x:array[i-1].x+array[i-1].width+super.distance,time:0.5, transition:"easeOut"});
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: