Flash/AS2:向下滚动越远,应用程序就越慢
我在 Flash 中构建了一个应用程序,它是一个相当大的应用程序,运行得相当流畅,但是它是一长串图形,运行得比应用程序窗口更远,所以我使用垂直滚动条和遮罩来显示它们。
问题是,当您进一步向下滚动时,一切都会变得不稳定,任何补间或运动以及帧速率总体上看起来都要低得多。
当你到达底部时,虽然整个卷轴中有相同数量的影片剪辑和相同数量的细节,但它是难以忍受的,所以我不明白为什么应该有如此巨大的性能损失,因为下降了一点。
任何人都对可能导致此问题的原因有任何想法吗?
根据此处的要求,这是我构建图表的代码部分:
var local_data = SharedObject.getLocal("user_data");
Slide_Tracker = local_data.data.user_data;
var timespan:MovieClip = this.timescale.span;
for (i=0; i<Slide_Tracker.length; i++) {
var current_date = new Date(Slide_Tracker[i].date_int);
var date_int:Number = Slide_Tracker[i].date_int;
var x_range:Number = 30;
var sorted_date:Object = new Object(sortDate(Slide_Tracker[i].date_int));
var date_string:String = sorted_date.string;
var startX:Number = 0;
date_nav.push(Slide_Tracker[i].date_int);
if (i == 0) {
for (s=0; s<Graphs.length; s++) {
var Chart:MovieClip = Graphs[s].chartArea.createEmptyMovieClip("chart", 10);
Chart._x = 0;
Chart._y = 0;
Charts.push(Chart);
Chart._parent.dotSpace.index = s;
Chart._parent.dotSpace.onRollOver = function() {
this.followDot._visible = true;
this.followDot.enabled = false;
this.onMouseMove = function() {
if(this._parent.chart.viewPortRatio == undefined) {
var viewPortRatio:Number = 1;
}
else {
var viewPortRatio:Number = this._parent.chart.viewPortRatio;
}
var xMouse:Number = this._xmouse;
var xToArray:Number = Math.round(((xMouse-this._parent.chart._x)*viewPortRatio));
this.followDot._y = lineArray[this.index][xToArray].y;
trace(xToArray);
this.followDot._x = xMouse;
};
};
Chart._parent.dotSpace.onRollOut = function() {
this.followDot._visible = false;
delete this.onMouseMove;
};
}
} else if (i>0) {
var past_date:Date = new Date(Slide_Tracker[i-1].date_int);
var date_diff:Number = Math.round((current_date-past_date)/86400000);
}
for (s=0; s<Slide_Tracker[i].val_arr.length; s++) {
var Slide_y:Number = 100-Slide_Tracker[i].val_arr[s];
var Chart:MovieClip = Graphs[s].chartArea.chart;
with (Chart) {
beginFill(0x000066,15);
lineStyle(2,0x000066,80);
if (i == 0) {
moveTo(startX,Slide_y);
Xcoords[s].push(startX);
Ycoords[s].push(Slide_y);
} else if (i>0) {
var index:Number = Xcoords[s].length-1;
var prevX:Number = Xcoords[s][index];
var prevY:Number = Ycoords[s][index];
moveTo(prevX,prevY);
var newX:Number = prevX+(date_diff*(895.9/x_range));
var newY:Number = Slide_y;
lineTo(newX,newY);
lineStyle(6,0x000066,0);
lineTo(newX,100);
lineTo(prevX,100);
lineTo(prevX,prevY);
convertLineToArray(s,prevX,newX,prevY,newY);
Xcoords[s].push(newX);
Ycoords[s].push(newY);
}
endFill();
lineStyle(0,0x000066,80);
with (Graphs[s].chartArea.timescale.span) {
var barName:String = Slide_Tracker[i].date_int;
var thisBar:MovieClip = attachMovie("bar", barName, this.getNextHighestDepth()+i);
if (Slide_y != 100) {
var barY:Number = 100-Slide_y;
} else {
var barY:Number = 0;
}
if (i == 0) {
thisBar._x = 1;
thisbar._height = barY/4;
spanXcoords[s].push(1);
spanYcoords[s].push(barY/4);
} else if (i>0) {
var index:Number = spanXcoords[s].length-1;
var spanPrevX:Number = spanXcoords[s][index];
var spanPrevY:Number = spanYcoords[s][index];
var spanNewX:Number = spanPrevX+(date_diff*3);
var spanNewY:Number = barY/4;
thisBar._x = spanNewX;
thisBar._height = barY/4;
spanXcoords[s].push(spanNewX);
spanYcoords[s].push(spanNewY);
}
thisBar._y += 25;
selector_bars[s].push(thisBar);
}
}
Chart.setMask(Chart._parent.chart_mask);
var dot_name:String = new String(Graphs[s]._name+"_dot"+i);
var dotObj:Object = new Object();
if (prevX != undefined) {
dotObj._x = newX;
} else {
dotObj._x = startX;
}
dotObj._y = Slide_y;
Chart._parent.dotArea.attachMovie("graph_dot",dot_name,Graphs[s].chartArea.dotArea.getNextHighestDepth(),dotObj);
Chart._parent.dotArea.swapDepths(99999);
var thisDot:MovieClip = eval(Graphs[s]+".chartArea.dotArea."+dot_name);
Graphs_dots[s].push(thisDot);
thisDot.date_string = date_string;
thisDot.date_int = date_int;
thisDot.percent = Slide_Tracker[i].val_arr[s];
thisDot.onRollOver = function() {
this.gotoAndStop("over");
var dot_Coords:Object = {x:this._x, y:this._y};
var viewPortRatio:Number = this._parent._parent.chart.viewPortRatio;
var offsetX:Number = this._parent._parent.chart.offsetX;
if (viewPortRatio == undefined) {
viewPortRatio = 1;
}
if (offsetX == undefined) {
offsetX = 0;
}
var text_x:Number = (dot_Coords.x/viewPortRatio)+offsetX;
var text_y:Number = dot_Coords.y;
if (dot_Coords.y<50) {
text_y += 60;
} else {
text_y -= 20;
}
var Textbox:Object = {name:"dot_info", container:this._parent._parent._parent, x:text_x, y:text_y, text:this.date_string+"\n"+this.percent+"%"};
var dotText:TextField = generateTextbox(Textbox);
if (dotText._x>448) {
dotText._x -= dotText._width;
}
};
thisDot.onRollOut = thisDot.onReleaseOutside=function () {
this.gotoAndStop("norm");
killTxt(this._parent._parent._parent.dot_info);
delete dot_Coords;
};
}
chartsWidth = Chart._width;
}
这是我的滚动条代码:
scrolling = function () {
var scrollHeight:Number = scrollTrack._height - btnUp._height - btnDown._height;
var contentHeight:Number = contentMain._height;
var scrollFaceHeight:Number = scrollFace._height;
var maskHeight:Number = maskedView._height;
var initPosition:Number = scrollFace._y=scrollTrack._y + btnUp._height;
var initContentPos:Number = contentMain._y;
var finalContentPos:Number = maskHeight-contentHeight+initContentPos;
var left:Number = scrollTrack._x + (scrollTrack._width - scrollFace._width)/2.4;
var top:Number = scrollTrack._y + btnUp._height;
var right:Number = scrollTrack._x + (scrollTrack._width - scrollFace._width)/2.4;
var bottom:Number = (scrollTrack._height-scrollFaceHeight+scrollTrack._y) - btnDown._height;
var dy:Number = 0;
var speed:Number = 10;
var moveVal:Number = (contentHeight-maskHeight)/(scrollHeight-scrollFaceHeight);
scrollFace.onPress = function() {
var currPos:Number = this._y;
startDrag(this, false, left, top, right, bottom);
this.onMouseMove = function() {
dy = Math.abs(initPosition-this._y);
contentMain._y = Math.round(dy*-1*moveVal+initContentPos);
};
};
scrollFace.onMouseUp = function() {
stopDrag();
delete this.onMouseMove;
};
btnUp.onPress = function() {
this.onEnterFrame = function() {
if (contentMain._y+speed<maskedView._y) {
if (scrollFace._y<=top) {
scrollFace._y = top;
} else {
scrollFace._y -= speed/moveVal;
}
contentMain._y += speed;
} else {
scrollFace._y = top;
contentMain._y = maskedView._y;
delete this.onEnterFrame;
}
};
};
btnUp.onDragOut = function() {
delete this.onEnterFrame;
};
btnUp.onRollOut = function() {
delete this.onEnterFrame;
};
btnDown.onPress = function() {
this.onEnterFrame = function() {
if (contentMain._y-speed>finalContentPos) {
if (scrollFace._y>=bottom) {
scrollFace._y = bottom;
} else {
scrollFace._y += speed/moveVal;
}
contentMain._y -= speed;
} else {
scrollFace._y = bottom;
contentMain._y = finalContentPos;
delete this.onEnterFrame;
}
};
};
btnDown.onRelease = function() {
delete this.onEnterFrame;
};
btnDown.onDragOut = function() {
delete this.onEnterFrame;
};
var mouseListener = new Object();
mouseListener.onMouseWheel = function( wheelMotion )
{
if (wheelMotion < 0) {
if (contentMain._y-speed>finalContentPos) {
if (scrollFace._y>=bottom) {
scrollFace._y = bottom;
} else { scrollFace._y += speed/moveVal;
}
contentMain._y -= speed;
} else {
scrollFace._y = bottom;
contentMain._y = finalContentPos;
}
}
if (wheelMotion > 0) {
if (contentMain._y+speed<maskedView._y) {
if (scrollFace._y<=top) {
scrollFace._y = top;
} else {
scrollFace._y -= speed/moveVal;
}
contentMain._y += speed;
} else {
scrollFace._y = top;
contentMain._y = maskedView._y;
}
}
}
Mouse.addListener( mouseListener );
if (contentHeight<maskHeight) {
scrollFace._visible = false;
btnUp.enabled = false;
btnDown.enabled = false;
btnUp.gotoAndStop(2);
btnDown.gotoAndStop(2);
} else {
scrollFace._visible = true;
btnUp.enabled = true;
btnDown.enabled = true;
btnUp.gotoAndStop(1);
btnDown.gotoAndStop(1);
}
};
scrolling();
I have built an application in flash, it is rather a large application that runs pretty smoothly, however it is a long list of graphs that run further than the application window so I use a vertical scrollbar and a mask to display them.
The problem is everything becomes choppy the further you scroll down, any Tweens or movement and the framerate in general just appears to be much much lower.
When you get to the bottom it is unbearable although there is the same amount of movieclips and same amount of detail throughout the scroll, so I don't see why there should be this massive performance hit for going down a bit.
Anyone have any ideas as to what could be causing this?
As requested here is the part of my code which builds the graphs:
var local_data = SharedObject.getLocal("user_data");
Slide_Tracker = local_data.data.user_data;
var timespan:MovieClip = this.timescale.span;
for (i=0; i<Slide_Tracker.length; i++) {
var current_date = new Date(Slide_Tracker[i].date_int);
var date_int:Number = Slide_Tracker[i].date_int;
var x_range:Number = 30;
var sorted_date:Object = new Object(sortDate(Slide_Tracker[i].date_int));
var date_string:String = sorted_date.string;
var startX:Number = 0;
date_nav.push(Slide_Tracker[i].date_int);
if (i == 0) {
for (s=0; s<Graphs.length; s++) {
var Chart:MovieClip = Graphs[s].chartArea.createEmptyMovieClip("chart", 10);
Chart._x = 0;
Chart._y = 0;
Charts.push(Chart);
Chart._parent.dotSpace.index = s;
Chart._parent.dotSpace.onRollOver = function() {
this.followDot._visible = true;
this.followDot.enabled = false;
this.onMouseMove = function() {
if(this._parent.chart.viewPortRatio == undefined) {
var viewPortRatio:Number = 1;
}
else {
var viewPortRatio:Number = this._parent.chart.viewPortRatio;
}
var xMouse:Number = this._xmouse;
var xToArray:Number = Math.round(((xMouse-this._parent.chart._x)*viewPortRatio));
this.followDot._y = lineArray[this.index][xToArray].y;
trace(xToArray);
this.followDot._x = xMouse;
};
};
Chart._parent.dotSpace.onRollOut = function() {
this.followDot._visible = false;
delete this.onMouseMove;
};
}
} else if (i>0) {
var past_date:Date = new Date(Slide_Tracker[i-1].date_int);
var date_diff:Number = Math.round((current_date-past_date)/86400000);
}
for (s=0; s<Slide_Tracker[i].val_arr.length; s++) {
var Slide_y:Number = 100-Slide_Tracker[i].val_arr[s];
var Chart:MovieClip = Graphs[s].chartArea.chart;
with (Chart) {
beginFill(0x000066,15);
lineStyle(2,0x000066,80);
if (i == 0) {
moveTo(startX,Slide_y);
Xcoords[s].push(startX);
Ycoords[s].push(Slide_y);
} else if (i>0) {
var index:Number = Xcoords[s].length-1;
var prevX:Number = Xcoords[s][index];
var prevY:Number = Ycoords[s][index];
moveTo(prevX,prevY);
var newX:Number = prevX+(date_diff*(895.9/x_range));
var newY:Number = Slide_y;
lineTo(newX,newY);
lineStyle(6,0x000066,0);
lineTo(newX,100);
lineTo(prevX,100);
lineTo(prevX,prevY);
convertLineToArray(s,prevX,newX,prevY,newY);
Xcoords[s].push(newX);
Ycoords[s].push(newY);
}
endFill();
lineStyle(0,0x000066,80);
with (Graphs[s].chartArea.timescale.span) {
var barName:String = Slide_Tracker[i].date_int;
var thisBar:MovieClip = attachMovie("bar", barName, this.getNextHighestDepth()+i);
if (Slide_y != 100) {
var barY:Number = 100-Slide_y;
} else {
var barY:Number = 0;
}
if (i == 0) {
thisBar._x = 1;
thisbar._height = barY/4;
spanXcoords[s].push(1);
spanYcoords[s].push(barY/4);
} else if (i>0) {
var index:Number = spanXcoords[s].length-1;
var spanPrevX:Number = spanXcoords[s][index];
var spanPrevY:Number = spanYcoords[s][index];
var spanNewX:Number = spanPrevX+(date_diff*3);
var spanNewY:Number = barY/4;
thisBar._x = spanNewX;
thisBar._height = barY/4;
spanXcoords[s].push(spanNewX);
spanYcoords[s].push(spanNewY);
}
thisBar._y += 25;
selector_bars[s].push(thisBar);
}
}
Chart.setMask(Chart._parent.chart_mask);
var dot_name:String = new String(Graphs[s]._name+"_dot"+i);
var dotObj:Object = new Object();
if (prevX != undefined) {
dotObj._x = newX;
} else {
dotObj._x = startX;
}
dotObj._y = Slide_y;
Chart._parent.dotArea.attachMovie("graph_dot",dot_name,Graphs[s].chartArea.dotArea.getNextHighestDepth(),dotObj);
Chart._parent.dotArea.swapDepths(99999);
var thisDot:MovieClip = eval(Graphs[s]+".chartArea.dotArea."+dot_name);
Graphs_dots[s].push(thisDot);
thisDot.date_string = date_string;
thisDot.date_int = date_int;
thisDot.percent = Slide_Tracker[i].val_arr[s];
thisDot.onRollOver = function() {
this.gotoAndStop("over");
var dot_Coords:Object = {x:this._x, y:this._y};
var viewPortRatio:Number = this._parent._parent.chart.viewPortRatio;
var offsetX:Number = this._parent._parent.chart.offsetX;
if (viewPortRatio == undefined) {
viewPortRatio = 1;
}
if (offsetX == undefined) {
offsetX = 0;
}
var text_x:Number = (dot_Coords.x/viewPortRatio)+offsetX;
var text_y:Number = dot_Coords.y;
if (dot_Coords.y<50) {
text_y += 60;
} else {
text_y -= 20;
}
var Textbox:Object = {name:"dot_info", container:this._parent._parent._parent, x:text_x, y:text_y, text:this.date_string+"\n"+this.percent+"%"};
var dotText:TextField = generateTextbox(Textbox);
if (dotText._x>448) {
dotText._x -= dotText._width;
}
};
thisDot.onRollOut = thisDot.onReleaseOutside=function () {
this.gotoAndStop("norm");
killTxt(this._parent._parent._parent.dot_info);
delete dot_Coords;
};
}
chartsWidth = Chart._width;
}
And here is my scrollbar code:
scrolling = function () {
var scrollHeight:Number = scrollTrack._height - btnUp._height - btnDown._height;
var contentHeight:Number = contentMain._height;
var scrollFaceHeight:Number = scrollFace._height;
var maskHeight:Number = maskedView._height;
var initPosition:Number = scrollFace._y=scrollTrack._y + btnUp._height;
var initContentPos:Number = contentMain._y;
var finalContentPos:Number = maskHeight-contentHeight+initContentPos;
var left:Number = scrollTrack._x + (scrollTrack._width - scrollFace._width)/2.4;
var top:Number = scrollTrack._y + btnUp._height;
var right:Number = scrollTrack._x + (scrollTrack._width - scrollFace._width)/2.4;
var bottom:Number = (scrollTrack._height-scrollFaceHeight+scrollTrack._y) - btnDown._height;
var dy:Number = 0;
var speed:Number = 10;
var moveVal:Number = (contentHeight-maskHeight)/(scrollHeight-scrollFaceHeight);
scrollFace.onPress = function() {
var currPos:Number = this._y;
startDrag(this, false, left, top, right, bottom);
this.onMouseMove = function() {
dy = Math.abs(initPosition-this._y);
contentMain._y = Math.round(dy*-1*moveVal+initContentPos);
};
};
scrollFace.onMouseUp = function() {
stopDrag();
delete this.onMouseMove;
};
btnUp.onPress = function() {
this.onEnterFrame = function() {
if (contentMain._y+speed<maskedView._y) {
if (scrollFace._y<=top) {
scrollFace._y = top;
} else {
scrollFace._y -= speed/moveVal;
}
contentMain._y += speed;
} else {
scrollFace._y = top;
contentMain._y = maskedView._y;
delete this.onEnterFrame;
}
};
};
btnUp.onDragOut = function() {
delete this.onEnterFrame;
};
btnUp.onRollOut = function() {
delete this.onEnterFrame;
};
btnDown.onPress = function() {
this.onEnterFrame = function() {
if (contentMain._y-speed>finalContentPos) {
if (scrollFace._y>=bottom) {
scrollFace._y = bottom;
} else {
scrollFace._y += speed/moveVal;
}
contentMain._y -= speed;
} else {
scrollFace._y = bottom;
contentMain._y = finalContentPos;
delete this.onEnterFrame;
}
};
};
btnDown.onRelease = function() {
delete this.onEnterFrame;
};
btnDown.onDragOut = function() {
delete this.onEnterFrame;
};
var mouseListener = new Object();
mouseListener.onMouseWheel = function( wheelMotion )
{
if (wheelMotion < 0) {
if (contentMain._y-speed>finalContentPos) {
if (scrollFace._y>=bottom) {
scrollFace._y = bottom;
} else { scrollFace._y += speed/moveVal;
}
contentMain._y -= speed;
} else {
scrollFace._y = bottom;
contentMain._y = finalContentPos;
}
}
if (wheelMotion > 0) {
if (contentMain._y+speed<maskedView._y) {
if (scrollFace._y<=top) {
scrollFace._y = top;
} else {
scrollFace._y -= speed/moveVal;
}
contentMain._y += speed;
} else {
scrollFace._y = top;
contentMain._y = maskedView._y;
}
}
}
Mouse.addListener( mouseListener );
if (contentHeight<maskHeight) {
scrollFace._visible = false;
btnUp.enabled = false;
btnDown.enabled = false;
btnUp.gotoAndStop(2);
btnDown.gotoAndStop(2);
} else {
scrollFace._visible = true;
btnUp.enabled = true;
btnDown.enabled = true;
btnUp.gotoAndStop(1);
btnDown.gotoAndStop(1);
}
};
scrolling();
我今天解决了这个问题,真是松了一口气,我刚刚遇到了
scrollRect()
函数,它只渲染在其边界内可见的数据,只要它是位图缓存的(矢量对象仍然会被渲染)完整的,无论是否可见)。尽管事实上我让用户修改图形的 _scaleX 并将它们缓存为位图,但自从用可滚动矩形交换蒙版后,我仍然看到绝对巨大的性能提升,因为在有足够的数据后,这些图形的宽度超过 20,000。尽管它们的体积巨大,但一切都运行流畅。
Adobe 对
scrollRect() 的解释
I solved this today and what a relief, I just ran into the
scrollRect()
function which only renders the data which is viewable within it's bounds as long as it is bitmap cached (vector objects will still be rendered in full whether viewable or not).Despite the fact I let the user modify the _scaleX of the graphs and caching them as a bitmap now I still see an absolutely huge performance increase since swapping my masks with a scrollable rectangle, as after enough data these graphs were over 20,000 in width. Despite their humongous size everything works fluidly.
Adobe's explanation of
scrollRect()