我附上了一个可以在 CS 5.5 中运行的带有 FLA 的 zip。动画包含一个性能分析器和滑块来控制各种参数。
演示: http ://separdi.ehclients.com/alivetest/index.html 点击任意位置开始动画
文件: https ://www.dropbox.com/s/4rcpvzo1h7br8fh/alivesource.zip
我编写了一个程序,它逐个像素地绘制线条并以波浪状的方式对其进行动画处理,并使用置换贴图置换某些像素。
这是每个循环发生的情况:
- 前一个循环中的显示对象和变量被清除
- 位移图存储在位图数据对象中
- 通过读取存储在数组中的 y 坐标,逐像素绘制一条线。它的值也可以使用相应的位移图和正弦波数据进行更改。
我有设置滑块,您可以使用它来控制绘制的线数(linecount)、每条线的宽度(canvaswidth)和每条线的分辨率(res)。
性能很差,我希望您能帮助优化它。也许我无法优化我的代码,请告诉我。
我不认为缓存为位图数据是可能的,因为线条是永久运动的
请记住,我真的很想保留 35 行和每次迭代 1 像素的分辨率
非常感谢
更新:我现在使用 drawPath 来绘制线条,而不是逐个像素地绘制。
/*
Click anywhere on the stage to start anim
*/
import flash.display.BitmapData;
import com.greensock.*;
import flash.display.Shape;
import uk.co.soulwire.*;
import net.hires.debug.Stats;
import uk.co.soulwire.gui.SimpleGUI;
import flash.display.MovieClip;
import flash.display.Sprite;
/*
Performance analyser and variable sliders
*/
var stats:Stats;
var gui:SimpleGUI;
var guiholder:MovieClip;
stats=new Stats();
stats.x = 1200;
stats.y = 0;
addChild(stats);
gui = new SimpleGUI(this,"Parameters","h",1000,0);
gui.show();
/*
Stores the base coordinates
*/
var c:Coordinates;
c=new Coordinates();
/*
Holds the lines
*/
var holder:MovieClip = new MovieClip ;
addChild(holder);
/*
Generic variables
*/
var i:uint;
var j:uint;
var line:Sprite;
var lines:Array = [];
var bmd:BitmapData;
var brightness = 0;
var sinus = 0;
/**
*
Parameters used to control the animaitons and extrusions
*
**/
/*
How many pixels do we draw in each loop?
*/
var scaleFactor:Number=2
var canvasWidth:Number = 999;
var lineCount:Number = 35;
var res = 1;//Skip res-1 pixels per loop to lower the resolution
/*
Displacement map properties
*/
var extrusion:Number = 1;
var extrusiontarget:Number = .1;
var tolerance:Number = 1;
var smoothness = 10;
//Sinewave
var lasti = 0;
var sinedirection = -1;
var sineamplitude:Number = 3;
var sinespeed = 0.5;
var sinedensity = 100;
/*
Breathing animation
*/
var inhale:Number = 2;
var exhale:Number = 2;
var beforeInhale:Number = 0;
var beforeExhale:Number = 0;
/*
Add sliders to control the above variables
*/
gui.addGroup("Pixels being drawn");
gui.addSlider("lineCount", 5, 35);
gui.addSlider("canvasWidth",30,999);
gui.addSlider("res",1,10);
gui.addGroup("Displacement Map");
gui.addSlider("smoothness", 1, 100,{callback:setBlur});
gui.addSlider("tolerance", 1, 255);
gui.addSlider("extrusiontarget", 0.1, 3);
gui.addGroup("Sinwave");
gui.addSlider("sinedirection",-1,1);
gui.addSlider("sineamplitude",0,30);
gui.addSlider("sinespeed",0,10);
gui.addGroup("Breathing");
gui.addSlider("beforeInhale",0,5);
gui.addSlider("inhale",0,5);
gui.addSlider("beforeExhale",0,5);
gui.addSlider("exhale",0,5);
/**
Loop
**/
function myEnterFrame(event:Event):void {
/*
Start a new iteration of line drawing, triggered when you click anywhere ons tage
*/
drawLines();
}
function drawLines():void {
for (i=0; i<lines.length; i++) {
holder.removeChild(lines[i]);
lines[i] = null;
}
lines = [];
for (i=0; i<lineCount; i++) {
drawLine(i);
}
}
function resetBitmapData(){
bmd = null;
bmd = new BitmapData(canvasWidth,1000);
bmd.draw(mc);
mc.visible = false;
}
/**
plot the cordinates of each point absed on sin data and bmp brihgtness
**/
var targety:Number;
var myPath:GraphicsPath;
var myStroke:GraphicsStroke;
var myDrawing:Vector.<IGraphicsData > ;
var myFill:GraphicsSolidFill;
myFill= new GraphicsSolidFill();
myFill.color = 0x000000;
function drawLine(linenumber):void {
line=new Sprite();
holder.addChild(line);
myPath= new GraphicsPath(new Vector.<int>(), new Vector.<Number>());
myStroke = new GraphicsStroke(res);
myStroke.fill = new GraphicsSolidFill(0xff0000);// solid stroke
for (j=0; j<canvasWidth; j+=res) {
brightness = Math.ceil(getbrightness(getcolor(j,c.coords[linenumber][j]))/tolerance) ;
sinus= Math.sin((j + (lasti * sinespeed)) / sinedensity) * sineamplitude;
targety=c.coords[linenumber][j]-(sinus*0)-(brightness*extrusion)-(sinus*(linenumber-15)*1);
myPath.commands.push(2);
myPath.data.push(j,targety);
}
myPath.commands.push(2);
myPath.data.push(0,1000);
myDrawing = new Vector.<IGraphicsData>();
myDrawing.push(myStroke,myFill, myPath);
line.graphics.drawGraphicsData(myDrawing);
lines.push(line);
lasti -= sinedirection;
}
/*
Functions to retrieve brightness of displacement map
*/
function getcolor(xx,targety):uint {
var pixelValue:uint = bmd.getPixel(xx,targety);
return pixelValue;
}
function getbrightness(colour):Number {
var R:Number = 0;
var G:Number = 0;
var B:Number = 0;
R += colour >> 16 & 0xFF;
G += colour >> 8 & 0xFF;
B += colour & 0xFF;
var br = Math.sqrt(R * R * .241 + G * G * .691 + B * B * .068);
return br;
}
/*
Makes the displacment map "breathe"
*/
function grow():void {
TweenLite.to(this,inhale,{extrusion:extrusiontarget,onComplete:shrink,delay:beforeInhale});
}
function shrink():void {
TweenLite.to(this,exhale,{extrusion:0,onComplete:grow,delay:beforeExhale});
}
/*
Smoothness of displacement map
*/
var blur:BlurFilter = new BlurFilter();
function setBlur():void {
trace("sb");
blur.blurX = smoothness;
blur.blurY = smoothness;
blur.quality = BitmapFilterQuality.HIGH;
mc.word.filters = [blur];
//reset the bitmap data
resetBitmapData()
}
function mouseDownHandler(e) {
grow();
addEventListener(Event.ENTER_FRAME,myEnterFrame);
}
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
//Draws lines;
setBlur();
drawLines();
旧代码:
/*
Click anywhere on the stage to start anim
*/
import flash.display.BitmapData;
import com.greensock.*;
import flash.display.Shape;
import uk.co.soulwire.*;
import net.hires.debug.Stats;
import uk.co.soulwire.gui.SimpleGUI;
import flash.display.MovieClip;
/*
Performance analyser and variable sliders
*/
var stats:Stats;
var gui:SimpleGUI;
var guiholder:MovieClip;
stats=new Stats();
stats.x = 1200
stats.y = 0;
addChild(stats);
gui = new SimpleGUI(this,"Parameters","h",1000,0);
gui.show();
/*
Stores the base coordinates
*/
var c:Coordinates;
c=new Coordinates();
/*
Holds the lines
*/
var holder:MovieClip=new MovieClip
addChild(holder)
/*
Generic variables
*/
var i:uint;
var j:uint;
var line:Shape;
var lines:Array = [];
var bmd:BitmapData;
var brightness = 0;
var sinus=0;
/**
*
Parameters used to control the animaitons and extrusions
*
**/
/*
How many pixels do we draw in each loop?
*/
var canvaswidth:Number = 999;
var linecount:Number=35
var res=2//Skip res-1 pixels per loop to lower the resolution
/*
Displacement map properties
*/
var extrusion:Number = 1;
var extrusiontarget:Number = .1;
var tolerance:Number = 1;
var smoothness = 10;
//Sinewave
var lasti = 0;
var sinedirection = -1;
var sineamplitude:Number = 3;
var sinespeed = 0.5;
var sinedensity = 100;
/*
Breathing animation
*/
var inhale:Number = 2;
var exhale:Number = 2;
var beforeInhale:Number = 0;
var beforeExhale:Number = 0;
/*
Add sliders to control the above variables
*/
gui.addGroup("Pixels being drawn")
gui.addSlider("linecount", 5, 35);
gui.addSlider("canvaswidth",30,999);
gui.addSlider("res",1,10);
gui.addGroup("Displacement Map")
gui.addSlider("smoothness", 1, 100,{callback:setblur});
gui.addSlider("tolerance", 1, 255);
gui.addSlider("extrusiontarget", 0.1, 3);
gui.addGroup("Sinwave")
gui.addSlider("sinedirection",-1,1);
gui.addSlider("sineamplitude",0,30);
gui.addSlider("sinespeed",0,10);
gui.addGroup("Breathing")
gui.addSlider("beforeInhale",0,5);
gui.addSlider("inhale",0,5);
gui.addSlider("beforeExhale",0,5);
gui.addSlider("exhale",0,5);
/**
Loop
**/
function myEnterFrame(event:Event):void {
/*
Start a new iteration of line drawing, triggered when you click anywhere ons tage
*/
initdraw();
}
/**
Clear the lines
Clear the bmp data
Redraw the bitmpa data
Redraw the lines
**/
function initdraw():void {
/*
Clear previous lines and displacement map data
Lance drawing of 35 lines
*/
for (i=0; i<lines.length; i++) {
holder.removeChild(lines[i]);
lines[i] = null;
}
bmd = null;
bmd = new BitmapData(canvaswidth,400);
bmd.draw(mc);
lines = [];
for (i=0; i<35; i++) {
// for (i=0; i<c.coords.length; i++) {
drawlines(i);
}
}
/**
plot the cordinates of each point absed on sin data and bmp brihgtness
**/
function drawlines(linenumber):void {
/*
Start to draw a line
*/
line =new Shape();
line.graphics.lineStyle(1, 0xdddddd);
line.graphics.beginFill(0x000000);
line.graphics.moveTo(-1,0);
/*
Increase length by 1 * times resolution and
Adjust y values based on displacement map and sinewave data
*/
for (j=0; j<canvaswidth; j+=res) {
if (c.coords[linenumber][j] ==1100) {
line.graphics.lineStyle(1, 0x000000);
} else {
line.graphics.lineStyle(1, 0xFFffff);
}
brightness = Math.ceil(getbrightness(getcolor(j,c.coords[linenumber][j]))/tolerance) ;
sinus= Math.sin((j + (lasti * sinespeed)) / sinedensity) * sineamplitude;
line.graphics.lineTo(j,c.coords[linenumber][j]-sinus-(brightness*extrusion));
}
/*
Close the path that the line is drawing
*/
lasti -= sinedirection;
line.graphics.lineTo(500,1100);
line.graphics.lineTo(-1,1100);
line.graphics.endFill();
lines.push(line);
holder.addChild(line);
}
/*
Smoothness of displacement map
*/
var blur:BlurFilter = new BlurFilter();
function setblur():void {
trace("sb");
blur.blurX = smoothness;
blur.blurY = smoothness;
blur.quality = BitmapFilterQuality.HIGH;
mc.word.filters = [blur];
}
/*
Functions to retrieve brightness of displacement map
*/
function getcolor(xx,yy):uint {
var pixelValue:uint = bmd.getPixel(xx,yy);
return pixelValue;
}
function getbrightness(colour):Number {
var R:Number = 0;
var G:Number = 0;
var B:Number = 0;
R += colour >> 16 & 0xFF;
G += colour >> 8 & 0xFF;
B += colour & 0xFF;
var br = Math.sqrt(R * R * .241 + G * G * .691 + B * B * .068);
return br;
}
/*
Makes the displacment map stringer then weaker
*/
function grow():void {
TweenLite.to(this,inhale,{extrusion:extrusiontarget,onComplete:shrink,delay:beforeInhale});
}
function shrink():void {
TweenLite.to(this,exhale,{extrusion:0,onComplete:grow,delay:beforeExhale});
}
function mouseDownHandler(e){
grow();
addEventListener(Event.ENTER_FRAME,myEnterFrame);
}
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
//Draws lines
initdraw();
setblur()